An email client for the addresses you already own. Reads over IMAP, sends over SMTP, and never keeps a copy of your mail.

Fixture data from the dev-only demo mode; every name and address is fictional.
Google removes "Send mail as" for third-party addresses in January 2027, after killing POP fetch and Gmailify in January 2026. If you send from a domain you own through Gmail's interface, that stops working. YOZZ is the client for that case: add any address with an IMAP or SMTP server and send from it, with no limit on how many. An address with no inbox attached is the normal case here, not an error.
The other half is what YOZZ leaves out. It has fewer features than Gmail on purpose: one dark surface, threads, archive, trash, stars, a Markdown composer. Every addition has to displace something.
The browser does the mail. It opens TLS 1.3 to your IMAP and SMTP servers itself, with a TLS and X.509 implementation in TypeScript, and reaches them through a relay on our side that forwards bytes it cannot read. Your mail passwords never leave your device: YOZZ stores them encrypted with a key only you hold, and our servers keep ciphertext they cannot open. If we were breached or subpoenaed, there is nothing to hand over.
Your mail itself is not encrypted; it is wherever it already lives. So this is not a "zero-knowledge email client", and we don't call it one. It adds nothing to your attack surface, which is the smaller and true claim.
Received HTML renders in a sandboxed frame with no network, remote images off until you ask, and a switch to the sender's plain-text part. Inbox and Sent are threaded together and cached on the device; nothing is synced through us.
Early. The hosted app at yozz.app is the one we use ourselves and it is not finished: no mobile app, no notifications while the tab is closed, one live connection per address while the tab is visible. The protocol libraries are the mature part; the numbers they must print are in docs/gates.md.
This repository is an exported copy of a private monorepo, so it has no pull requests and its
history is one commit per snapshot. Self-hosting is possible (apps/worker-api/wrangler.jsonc
and .dev.vars.example list what the worker needs) but not something we document or support.
packages/ is what you can install from npm, MIT. internal/ is workspace-only code the apps
share, and apps/ is what runs at yozz.app; both AGPL-3.0.
| Package | What it is | Licence |
|---|---|---|
packages/x509 | Strict DER, certificate decoding, RFC 5280 path validation, a compiled trust store built from curl's cacert.pem. x509-limbo: 902/902 accepts, 8827/8837 rejects, each over-accept attributed. | MIT |
packages/tls | A TLS 1.3 client (RFC 9846): record layer, handshake state machine, key schedule, PSK resumption (never 0-RTT), KeyUpdate, TOFU SPKI pinning. RFC 8448 byte-exact on all five traces; BoGo 296/296. | MIT |
packages/imap | Transport-agnostic IMAP4rev2/rev1 client: literals, total parsing, RFC 2047, SASL PLAIN and LOGIN, IDLE, UID MOVE. | MIT |
packages/smtp | Transport-agnostic SMTP client plus an RFC 5322 message builder. | MIT |
internal/vault | The key schedule, DEK wrap and AES-GCM records for the encrypted settings store. | AGPL-3.0 |
internal/vault-contract | Wire schemas for the vault HTTP API. | AGPL-3.0 |
apps/worker-api | Hono + Better Auth on Cloudflare Workers: the vault routes, the D1 migrations and the relay, a session-gated WebSocket-to-TCP pipe to ports 993 and 465 only. | AGPL-3.0 |
apps/web | The Vite/React app. | AGPL-3.0 |
The TLS and X.509 packages run in Node and in all three browser engines, with no native code.
They are the parts most likely to be useful outside YOZZ, which is why they are MIT and on npm:
pnpm add @yozz.app/tls @yozz.app/x509 (and @yozz.app/imap, @yozz.app/smtp). Each package's
README has a short example; src/index.ts is its contract.
Needs Node 26 and pnpm (the version in package.json's packageManager).
pnpm install
cp apps/worker-api/.dev.vars.example apps/worker-api/.dev.vars # set BETTER_AUTH_SECRET to any 32+ chars
pnpm -F @yozz.app/worker-api db:migrate:local # migrations into wrangler dev's local D1
pnpm -F @yozz.app/worker-api dev # http://localhost:8787; magic links print here
VITE_API_URL=http://localhost:8787 pnpm -F @yozz.app/web dev # http://localhost:5177Open /welcome, enter an address, paste the magic link printed in the wrangler terminal into the
same tab, pick an unlock mode, then add a mail address under /connect. Passkey unlock needs a
PRF-capable authenticator (Chrome with Google Password Manager, or Safari with iCloud Keychain).
pnpm check, pnpm typecheck and pnpm test are the floor; CI runs them on every push.
docs/gates.md lists every suite, how to run it and the numbers it must print,
including the two exhaustive ones that are not in pnpm test: x509-limbo for packages/x509
and BoringSSL's BoGo runner for packages/tls.
Issues are welcome. Pull requests are disabled, because this repository is an exported copy of a private monorepo (made with OpenRepo) and a patch merged here would be lost on the next snapshot. Describe the change in an issue, with a diff if you have one, and it will be applied in the source repo and credited.
AGPL-3.0 for the app and everything not listed as MIT above. The four protocol
libraries are MIT: packages/tls,
packages/x509, packages/imap,
packages/smtp.