Introducing vemail
Back in April I wrote a pair of posts about getting custom domain email running cheaply. The first covered receiving mail for free using Cloudflare Email Routing. The second covered the other half of the problem: sending — Gmail's "Send As" for a human typing a reply, Resend for an application dispatching mail on its own. That second post has done considerably better than I expected, and going back to it recently, I noticed the shape of what I'd left out.
I described Resend accurately but narrowly. The framing was: you call it from code, for onboarding sequences and password resets and receipts, the things your product needs to dispatch without a human present. All true. What I didn't mention, because it wasn't the subject of that post, is that Resend is not limited to that use case at all. It will happily handle a real mailbox — inbound and outbound both — for a human being to read and write from, the same as any provider you'd pay a monthly fee for. And I would be remiss not to say plainly that I've been doing exactly that for a while now, as internal tooling, in place of Office 365. I'll grant that Office 365 gives you a good deal more than a custom-domain mailbox — documents, calendars, a whole suite most people never fully use — but if the thing you actually want is somewhere to send and receive mail on your own domain, that's a lot of subscription sitting on top of a fairly narrow need.
So I had Claude take that internal tooling and clean it up: strip out the parts specific to how I run things, tighten what remained, and shape it into something anyone could deploy for themselves rather than something that only worked because I was the one operating it. A point of honesty is worth inserting right here, though. vemail is a stripped-down version of my internal instance, but "stripped down" refers to what's gone, not to what's missing in the sense of features held back. What's gone is the specificity: the quirks of my own environment, the assumptions that only made sense because I was the sole person who'd ever touch it, the configuration that fit one particular setup and nobody else's. What you're getting isn't a lesser edition of the thing I actually run day to day; it's the same client, with the parts that only made sense for me removed.
Today I'm releasing the result. This is vemail by Valeon.
vemail is a self-hosted, open-source email client. It sends and receives on a domain you own, through Resend, and nothing about it depends on Gmail, Proton, or any big-name provider sitting in the middle. The whole thing ships as a single Docker image running against a self-hosted Convex backend, which means the pitch is genuinely simple: a domain you already own, plus a free Resend account, plus vemail, gets you a real private inbox with the send-and-receive experience of Gmail or Proton — except you're the one hosting it, and you're the one who owns the data sitting inside it.
The inbox itself is reactive rather than something you sit and refresh. New mail lands the moment Resend's webhook delivers it, pushed straight through Convex's subscription model, and read state and starred state stay in sync across every device you're signed into without you doing anything to make that happen. It's also built for more than one person from the start — you invite people in, each person claims their own prefix@domain addresses, and each person sees only their own mail. There's no open registration; the whole thing is invite-only by design; the admin is the one who lets anyone else in.
Domains and addresses scale independently of each other, and the economics of that are worth spelling out. vemail supports as many domains as your Resend account itself permits — Resend's $20-a-month tier alone allows ten — and within any domain you add, you can claim as many prefixes and addresses as you want, with no ceiling from Resend at all; that limit only ever bites at the domain level, never at the address level. Pair that with multi-user support inside a single deployment, an entire organisation running on one instance with everyone holding their own private addresses, and the cost model looks nothing like the rest of the market. Most competitors charge per user, per inbox, per address, so a team of ten people wanting a couple of addresses each turns into ten or twenty line items on an invoice. Here the marginal cost of another person or another address is zero; the only real cost is the Resend plan, and Resend prices by domain, not by mailbox. Making that work cleanly took solving a genuine quirk: Resend broadcasts webhook events for every domain on an account to whichever single webhook URL you've configured, with no regard for which of those domains any particular vemail instance actually manages. If your Resend account carries more domains than one vemail deployment is responsible for — because you're running that account across several instances, say, or keeping some domains for something else entirely — vemail filters incoming webhook traffic down to only the domains it has registered and quietly drops the rest, so mail meant for elsewhere never leaks into an inbox that shouldn't see it.
Privacy was a deliberate design choice rather than an afterthought bolted on later. Remote images and tracking pixels are blocked by default, so nobody gets a read receipt off the back of an invisible one-pixel image just because you opened their message. Every sender carries a visible trust badge reflecting whether their SPF, DKIM, and DMARC actually check out — the same authentication mechanism the post on sending walked through in detail — so you can see at a glance whether a message is who it claims to be. Inbound HTML gets sanitised on arrival, before it ever reaches your screen.
None of that would matter much if the client itself felt like a stripped-down demo, so it doesn't. There's a proper rich-text composer, drafts that autosave as you write them, attachments, threaded conversations, reply, reply-all, and forward, undo-send for the message you regret the instant it leaves your outbox, labels, starring, archiving, trash, and a command-K palette that filters within whichever folder you're currently sitting in. Setup walks you through the exact DNS records you need against your domain and polls quietly in the background until verification comes through, rather than leaving you to guess whether you've got a record wrong. And your Resend API key and webhook secret never sit in a plaintext environment file waiting to be leaked — they're AES-256-GCM encrypted at rest, entered once through the admin dashboard. Two-factor authentication, light and dark themes, and a proper PWA round it out.
There is one thing worth being upfront about before anyone deploys this. vemail is not air-gapped, and it can't be. Resend delivers your inbound mail by calling a webhook, which means your instance has to be reachable from the public internet over HTTPS or inbound simply won't arrive — you'll be able to send just fine and never receive a thing. Run it behind a reverse proxy with a real domain and a certificate. If your DNS already lives on Cloudflare, a Cloudflare Tunnel is genuinely the path of least resistance here — no open ports, no certificates to manage by hand — and if that's unfamiliar territory, I wrote about setting one up for exactly this kind of use case back in February.
Deployment otherwise is a clone, a setup script that generates the four secrets you need into a .env file, a few values edited to match your host, and docker compose up -d. The setup script pins the Convex instance secret deliberately, so the admin key stays valid across redeploys instead of forcing you through a deploy-generate-redeploy loop every time you touch the stack.
This is a first release rather than a finished one. What's there now is a complete daily driver — I've been living in it myself — but the roadmap is honest about what isn't built yet: a filters and rules engine, snooze and scheduled send and a vacation auto-responder, a proper contacts book, spam handling with per-recipient bounce suppression, .eml and mbox import and export, message templates, catch-all addresses, and multi-admin management. It's MIT licensed, the repository is open, and if any of that list appeals to you as something to build rather than wait for, contributions are genuinely welcome.
That closes the loop this series opened. The first post got you a receiving address for nothing. The second got you sending, human and programmatic both, still without a subscription. This one hands you the whole client — the thing sitting between those two halves, presenting your custom domain the way an inbox is actually meant to feel — and instead of just telling you how I built it, I'm giving you the tool itself.