Skip to content
← All work
PlatformsLiveWeb / API

OmniMail

One inbox, every account, pushed in real time — self-hosted.

OmniMail is a self-hosted webmail and calendar client that folds every IMAP, SMTP and CalDAV account into one command centre instead of a browser tab per provider. Persistent IMAP IDLE workers and Server-Sent Events push new mail to the browser the instant it arrives — no polling, no manual refresh — and replying to a thread always goes out through that thread's own authenticated SMTP identity.

Most webmail clients that aggregate several accounts turn into a browser-tab-per-provider habit anyway, because the aggregation is shallow: it polls, it drops attachments into a generic viewer, and a reply goes out from whichever account happened to be active. OmniMail treats aggregation as the actual product. Every connected IMAP, SMTP and CalDAV account lives inside one Next.js interface with resizable split-panes, and the backend keeps a persistent worker per mailbox rather than refetching on a timer.

Push, not polling

Each mail account gets its own long-lived imapflow connection running IMAP's IDLE command, so the server is told the moment a new message lands rather than asking every few minutes. That event streams to the browser over Server-Sent Events and triggers a Web Audio chime and a native notification — the inbox updates with no reload and no visible fetch.

Replies go out the door they came in

Replying to a thread dispatches through that account's own authenticated SMTP identity automatically, via nodemailer. There is no shared "from" address to misconfigure and no way for a reply on the work account to leave from the personal one.

Sandboxed by default

Incoming HTML mail is run through DOMPurify and rendered inside a sandboxed <iframe>, and remote images — the usual tracking-pixel vector — are blocked until a reader explicitly asks to load them. The composer is a full TipTap rich-text editor with CC/BCC chips and multi-file attachments, so writing mail does not feel like a step down from reading it.

Calendar in the same pane

A Schedule-X calendar grid connects to Google Calendar, Fastmail, iCloud, Nextcloud or a custom CalDAV endpoint via tsdav and ical.js, with Month, Week, Day and Agenda views and full recurrence support. It sits behind the same sidebar as the mail accounts, so a meeting invite and the calendar it belongs on are one click apart instead of two applications.

Running it

OmniMail ships as a single multi-stage Docker image against a PostgreSQL database, encrypts every stored credential with AES-256-GCM behind a scrypt-hashed master password, and idles under 150MB of RAM. It is MIT-licensed and self-hostable on anything that can run a container — no vendor account, no per-seat billing.

Capabilities

Real-time IMAP IDLE + SSE

A persistent worker per mailbox holds an IMAP IDLE connection open and streams new-mail events to the browser over Server-Sent Events, so nothing is ever polled.

Per-account SMTP identity

Replying to any thread routes automatically through that account's own authenticated SMTP credentials, so cross-account leakage is structurally impossible.

Sandboxed HTML rendering

Incoming mail is sanitised with DOMPurify and rendered in a sandboxed iframe; remote images and tracking pixels are blocked until explicitly loaded.

Unified CalDAV calendar

A Schedule-X grid overlays every synced CalDAV feed — Google, Fastmail, iCloud, Nextcloud or custom — with Month, Week, Day and Agenda views and recurrence.

Encrypted credential vault

IMAP, SMTP and CalDAV passwords are encrypted at rest with AES-256-GCM; the master password itself is scrypt-hashed, never stored in the clear.

One container, one process

Ships as a single Docker image against PostgreSQL, idling under 150MB of RAM — no message queue, no separate worker fleet to operate.

Screens

What it looks like in use.

Select any screen to view it full size. Use the arrow keys to move between screens and Escape to close.

  • Every connected account in one sidebar, with unread counts per account and per folder.
  • The Schedule-X calendar grid overlays every synced CalDAV feed in one month view.
  • Composing from the correct account — replies always leave through that account's own SMTP identity.

Next step

Tell us what is broken or what should exist.

Send the shape of the problem and any constraints you already know — budget, deadline, the stack you are stuck with. You will get a written reply from the engineer who would do the work, not a sales sequence.