Email on the edge. Sure.
A full-stack email framework for the edge. Inbound, outbound, threading, blob storage, classification, and a native IMAP server — all without a third-party inbox.
No edge SMTP. That would be a nightmare. But edge IMAP on Durable Objects? Absolutely. Bring your own auth, your own storage, your own routing. We ship the protocol layer and the data model.
Edge topology.
Your Worker is the mail exchange. Durable Objects pin IMAP sessions. Adapters connect the core to whatever backends you're already running.
What's in the box.
One package. Eight composable surfaces. All documented, all adapters, no magic globals.
Inbound
InboundAdapter, hand off to a handler. Attachments stream to blob storage. Returns a threaded message row.
Outbound
EmailProvider interface swaps Resend, Postmark, or SES without touching caller code.
Threading
References, In-Reply-To, Message-ID. No heuristic fuzz.
Blob storage
BlobStorage. R2 implementation ships; the interface is eight methods. Swap for S3 or whatever.
Classification
Newsletters
Native IMAP — on Durable Objects.
LOGIN, SELECT, FETCH, UID, IDLE, APPEND, SEARCH, flags, and the 23 other commands your client actually sends. Apple Mail and Thunderbird connect on TLS:993 without knowing the backend is a Worker.
Where it runs.
Latency, cost, sovereignty.
Email is mostly request/response with bursty fan-out. That is exactly what the edge is good at. Vendor lock-in on your inbox is not fine.
From SMTP-DATA accepted to row-written. Worker cold starts included. Your users' clients don't round-trip through Virginia.
Workers + D1 + R2 at published list price. No per-seat surcharge, no inbox retention tier, no "enterprise" line item.
Your D1, your R2, your logs. No vendor reads your customers' email. IMAP auth terminates at your AuthAdapter.
vs. self-hosted.
Postfix and Dovecot work. They have worked for twenty-five years. But if you haven't babysat a mail server through a PTR-record outage, you will.
| Concern | Postfix + Dovecot on a VPS | @rafters/mail |
|---|---|---|
| Inbound MX |
Run smtpd. Tune greylisting. Apply CVEs.
| Cloudflare Email Routing handles MX, SPF, DKIM, and spam. |
| Outbound SMTP | Your IP gets on a blocklist by Tuesday. | Hand off to Resend / Postmark / SES. Deliverability is their problem. |
| IMAP server | Dovecot on a long-lived VM. State in maildir. | Durable Object per user. State is a database row. |
| Storage | Disk fills up. Someone has to rotate it. | R2 for blobs, D1 for metadata. Infinite, indexed. |
| Scaling | Resize the VM. Pray the fsync survives. | Per-user isolate. Scales to zero when no one's checking mail. |
| Threading, classification, webhooks | You wire up Sieve, SpamAssassin, and a cron job. |
Built in. One InboundAdapter hook.
|
| Your 2AM pager | "disk 97% full on mail-01" | Silent. |
To be clear: we don't do edge SMTP. That would be a nightmare. Outbound goes through a real transactional provider. What we do is everything after the TCP handshake.
Objections.
The ones that come up in every DM.
Wait, IMAP on a Durable Object? Really?
IDLE pushes. A Durable Object is a single-threaded JS
instance with addressable state and a WebSocket-ish lifetime. That's the
same shape. The DO pins to a user, the Worker handles the auth, and a thin
port-993 process (Fly, Railway, Fargate, Docker, VPS) just
translates TLS frames into fetch() calls.
So you don't do outbound SMTP?
EmailProvider
interface — Resend, Postmark, and SES ship. You can write your own in about
forty lines.
What about spam, DKIM, and bounce handling?
inbound like any other message, with a
type: "bounce" tag.
Do I need Cloudflare?
Why would an AI agent need an inbox?
License?
Open source. MIT.
The whole thing lives at rafters-studio/mail. Issues welcome.
RFC nitpicks especially welcome.