Four domains. One usable mail system.
CMD Mail began with a practical ownership problem: I had several domains and wanted them to feel like one communication system. The result is a private service for myself and invited people, with a custom webmail experience and a real mail backend.
An account receives the same username across cmd.ag, cmd.boo, cli.fail, and ih8.tech. Those identities share one inbox, and any matching address can sign into the application. The domain becomes a choice of identity rather than a reason to maintain another separate mailbox.
Make address management predictable.
The Addresses screen can create a new name across all four domains or limit it to one selected domain. The complete bundle is checked for conflicts before creation, so a collision does not leave an accidental partial set of addresses.
Choosing a sending identity, drafting a message, reading replies, and handling attachments all happen in the same interface. The product work is in making those operations fit together, with account boundaries maintained as a user moves between addresses and messages.
Give everyday mail the details it needs.
Drafts save while you write, with a visible saving state and recovery when a request fails. Cc and Bcc stay with the draft, while Reply all preserves the relevant participants without adding the sender’s own identities back into the recipient list. Forwarding brings the message and its ordinary attachments into a reviewable composition.
Sending first enters a short, persistent Undo send window. Cancelling returns the message to a draft; once delivery has started, the interface does not pretend it can recall an email from another mail system. That boundary matters as much as the button itself.
A custom experience on a dedicated mail service.
React renders the mailbox and account interface. A Node and Express service manages invitations, sessions, profiles, and message workflows with SQLite, then talks to Stalwart through JMAP. Stalwart owns the mail store and protocol responsibilities.
Caddy provides the HTTPS edge, and Docker separates the services on the VPS. Authenticated SMTP2GO relay handles outgoing delivery; incoming mail follows the domains' MX configuration. My work connects those components into a coherent product rather than reimplementing a mail server inside the web application.
Let the email look like email.
Incoming messages often rely on tables, formatting, and embedded images. The viewer sanitizes markup and renders it in a script-disabled iframe. Inline images are checked against the signed-in account and the selected message, while external images require an explicit action.
Plain text remains available, and ordinary attachments keep their download flow. That combination restores the useful parts of a rich email, including recognizable signatures, while keeping a sender's content inside the message view.
A signature you can build, preview, and reuse.
The signature editor uses structured contact details and a live preview, with an account photo or the portfolio mark. It supports both contact emails and both websites. Outgoing messages include HTML and plain-text versions, carrying the selected image as an inline attachment.
The draft model stores composition separately from the rendered signature. Reopening and editing a draft therefore does not append another copy each time. Reply references survive that round trip too, keeping the visible composition experience aligned with the underlying email thread.
The deployment is part of the product.
Credentials stay outside source control, TLS certificates synchronize automatically, and daily consistent backups have an isolated restore-check path. Validation covered account isolation, hostile HTML, images, drafts, attachments, aliases, and internal delivery using temporary accounts.
A real relay test reached the recipient's Inbox, and the reply reached the owner's mailbox. That established a working round trip, while inbox placement still depends on the receiving service. Storage and relay quotas remain real limits, and the current backup copies are local to the VPS.