I've been using MXRoute for email hosting for a few years now. It's cheap, reliable, and gives you full control over your domains. The one thing it lacks is a decent webmail interface — Roundcube gets the job done but it feels like 2005.
So I built mxroot, a self-hosted webmail and account manager that talks to MXRoute's API for account management and uses standard IMAP/SMTP for mail access.
The stack
The backend is Go, using:
go-imapfor IMAP access (connection-per-request, simple enough for single-user)net/smtpwith STARTTLS for sendingmodernc.org/sqlitefor local state (pure Go, no CGO)- MXRoute's REST API for account/forwarder management
The frontend is React with Tailwind, nothing fancy. Top bar has domain and account selectors, an expandable management panel, and the main area shows the inbox.
Credential storage
The interesting part is password management. Each email account has its own IMAP password, and I wanted to store them securely without an external dependency like Vaultwarden. The solution: encrypt passwords with AES-256-GCM using a key derived from the app's master login password via Argon2id.
The encryption scheme is simple and portable:
salt (16 bytes) || nonce (12 bytes) || AES-256-GCM ciphertext
With the SQLite database file and the master password, you can decrypt all stored credentials offline using a short Python script. No lock-in.
Deployment
The whole thing runs as a single Docker container behind Caddy. Multi-stage Dockerfile: Node for the frontend build, Go for the backend, Alpine for the runtime. Total image size is around 30MB.
It's been working well for managing 12 accounts across 4 domains. The main limitation is that IMAP connections aren't pooled, so there's a small delay opening each mailbox. Good enough for personal use.