# mjl-/mox: a self-hosted mail server that configures itself

> Mox is an MIT-licensed Go mail server for one domain or a few, with SMTP, IMAP, webmail, SPF/DKIM/DMARC and automatic TLS in a single binary. The quickstart generates the config and prints the DNS records, but it assumes a dedicated machine and a root shell.

**mjl-/mox** — modern full-featured open source secure mail server for low-maintenance self-hosted email

- Repository: https://github.com/mjl-/mox
- Website: https://www.xmox.nl
- Stars: 5,878 · Forks: 228
- Language: Go
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/mjl-mox

## What mox is for, and who should run it

Mox targets a narrow case: you own one or a few domains and want to serve their email yourself without assembling Postfix, Dovecot, an ACME client and a spam filter into a working whole. The README describes it as a "modern full-featured open source secure mail server for low-maintenance self-hosted email", and the feature list is the argument: SMTP with extensions for receiving, submitting and delivering; IMAP4 with extensions for clients; webmail; SPF, DKIM and DMARC including aggregate reports; reputation tracking and Bayesian spam filtering that learn per user from Junk/Non-Junk classification; automatic TLS through ACME; DANE and MTA-STS.

The intended operator is one person or a small team running a mail server for their own domain, not a hosting provider. The quickstart assumes a machine dedicated to email, named [host].[domain] such as mail.example.com, with a DNSSEC-verifying resolver installed. The README is explicit that a machine which does not already run a webserver is "highly recommended", because modern email requires HTTPS and mox currently needs to run a webserver for automatic TLS with ACME. If you already run nginx or Apache on ports 80 and 443, you are outside the easy path; the README points to mox help quickstart for that case and warns it requires a lot more configuration. That is a real constraint, not a footnote.

The project is MIT-licensed, created by Mechiel Lukkien, and bundles BSD-3-claused code from the Go Authors plus the Mozilla Public Suffix List. It is written in Go and the last push was on 2026-09-13, with v0.0.17 released on 2026-08-19. Note the version number: 0.0.x. The README also carries a roadmap with items such as JMAP, CalDAV, encrypted storage of messages and TLS keys, and a mox setup command. Read that roadmap as a statement of what is not there yet.

## How mox is put together: one binary, four config files, four protocols

The repository layout tells most of the story. Top-level directories include smtp, imapserver, imapclient, dmarc, dkim, dmarcrpt, dane, dns, dnsbl, autotls, http, junk, dmarcdb and config, with main.go, localserve.go and ctl.go at the root. Each protocol area is its own package, and the README notes that most non-server Go packages mox consists of are written to be reusable. The binary is the composition of those packages: mox serve starts the listeners, and mox ctl talks to a running instance.

Configuration is split. mox.conf holds machine-level settings; domains.conf holds domains, accounts and aliases. The quickstart writes both, generates an admin password and an account password, and then prints the DNS records for the machine and domain. The web admin interface edits domains.conf, helps create accounts and list aliases, and shows status. That split matters operationally: domain and account changes are ordinary file edits, and the README lists modifying the configuration file as an admin-interface function.

On the wire, mox terminates SMTP on 25 for incoming delivery, 465 for submission with TLS, 587 for submission without initial TLS, IMAP on 993 and 143, and HTTP/HTTPS on 80 and 443. The Dockerfile exposes exactly those ports plus 8010 for Prometheus metrics. TLS certificates come from ACME, which is why the webserver is not optional in the default setup. Inbound and outbound delivery can use DANE and MTA-STS with STARTTLS, including REQUIRETLS, with TLSRPT reporting in both directions.

Anti-abuse is built into the delivery path rather than bolted on. Senders with no or low reputation, or with questionable message content, are slowed down in a way the README compares to greylisting. Rejected messages land in a mailbox called Rejects for a short period, which the README frames as a way to rescue legitimate synchronous signup, login or transactional mail that got misclassified. Reputation and Bayesian classification both learn per user from the Junk/Non-Junk decisions made in a mail client.

## Installing mox and running the quickstart

The README gives two ways to get the binary. You can download a build for linux/amd64 from the URL it lists, or compile it yourself with a Go toolchain of at least 1.24. The compile command downloads the latest release and writes the binary into the current directory:

```bash
GOBIN=$PWD CGO_ENABLED=0 go install github.com/mjl-/mox@latest
```

After that you have a file named mox. Symlink or rename it so the name is exactly mox, because the quickstart instructions invoke ./mox. Mox only compiles for and fully works on unix systems. It compiles for Windows, but mox serve does not yet work there; mox localserve and most other subcommands do. It does not compile for Plan 9.

The quickstart is the real install step. Run it as root, create a user and home directory for mox first, then run quickstart with the address you want to serve:

```bash
useradd -m -d /home/mox mox
cd /home/mox
./mox quickstart you@example.com
```

What you should see: mox creates mox.conf and domains.conf, adds the domain and an account for the address to domains.conf, generates an admin password and an account password, prints the DNS records to add for the machine and the domain, and prints commands to start mox and optionally install it as a service. The DNS records are the part you cannot skip; without them, SPF, DKIM, DMARC, MTA-STS and TLS validation will not line up for receivers. After starting, the admin web interface is reachable on internal IPs.

If you want to try mox before pointing a domain at it, the README offers mox localserve for a local test instance, including a pedantic mode. The docker-compose.yml shows how to publish the local ports on loopback, mapping container ports 1025, 1465, 1587, 1993, 1143, 1443 and 1080 to the host, with the -ip 0.0.0.0 flag so connections reach mox and IPv6 is not used. That is a sandbox for email-related testing and development, not a production path.

## Where mox gets in your way

The webserver dependency is the first wall. Mox needs ports 80 and 443 for ACME, MTA-STS and autoconfig, so a machine that already serves a website on those ports needs either a reverse-proxy arrangement the README calls a lot more configuration, or mox's own webserver, which can serve static files and forward requests. The README's own suggestion is to consider the built-in webserver, adding that it is "pretty good". That is a design decision with a cost: adopting mox means adopting its HTTP layer too, or doing manual certificate work.

The second wall is DNS. Mox prints the records but does not publish them. The roadmap lists automated DNS management and DANE/DKIM key rotation as future work, so today key rotation and record changes are manual. If your DNS provider has no API and a slow control panel, every DKIM rotation is a chore.

The third is the version number. At 0.0.17, the interface and configuration format can still move between releases, and the roadmap names features people often expect from a mail server: JMAP, CalDAV/iCal calendaring, encrypted storage of messages and TLS keys, and a mox setup command. None of those are described as shipped. If calendaring or JMAP is a requirement, mox is the wrong tool right now.

Docker is documented but explicitly not the recommended route. The README says it is important to run with docker host networking so mox can use the public IPs and get correct remote IP information for incoming connections, which matters for junk filtering and rate limiting. It also notes that new Docker images are not automatically generated for new Go runtime and compile releases. Host networking plus a mail server means the container is not buying you much isolation anyway.

Finally, the client story is partial. Account autodiscovery is implemented through SRV records, Microsoft-style and Thunderbird-style records, and Apple device management profiles, but the README itself adds that client support is limited. Expect to enter server settings by hand in some clients.

## How mox differs from running Postfix and Dovecot, and from Mailcow

The closest comparison in the repository's own framing is the traditional split stack. Postfix handles SMTP and hands messages to Dovecot for IMAP, with separate tools for spam scoring, DKIM signing, DMARC reporting and certificate renewal. Mox puts those in one process and one configuration model, and it cross-references the code with the relevant RFCs for readability. The practical difference is the failure surface: one binary and two config files instead of a set of daemons with their own logs, queues and reload semantics. The trade-off is that you get mox's choices for all of those layers, including its reputation and greylisting approach, rather than being able to swap in a different spam filter.

Mailcow is the other name that comes up in searches about mox, and the difference is packaging philosophy. Mailcow is a containerized suite with a web UI over a stack of established components; mox is a single Go binary with an embedded webserver, its own IMAP and SMTP implementations, and a JSON API for transactional sending and delivery events. If you want a familiar component set you can debug piece by piece, the suite approach fits better. If you want one thing to install, configure and upgrade, mox is the smaller surface. Neither is a drop-in replacement for the other, and migrating mailboxes between them is a separate project.

For local development and testing, the alternative to mox localserve is running a throwaway SMTP sink or a container of a test mail server. Mox's version is interesting because it runs the same code paths as production, including pedantic mode, which makes it useful for checking how a client behaves against a strict server.

## Upgrades, licence and what maintenance actually costs

The release history is uneven: v0.0.15 on 2025-04-18, then v0.0.16 on 2026-08-18 and v0.0.17 on 2026-08-19. The last push to the repository was on 2026-09-13. Long gaps between releases mean you should read release notes before jumping versions rather than assuming a steady cadence.

The Dockerfile builds from golang:1-alpine and copies the binary into alpine:latest, with the comment that using latest may break at some point but will hopefully be convenient most of the time. That is a moving base image. If you deploy the container, pin the image tag and digest as the docker-compose.yml comment suggests, rather than tracking latest.

Licensing is straightforward to read but not legal advice: mox is MIT-licensed, and the README states it includes BSD-3-claused code from the Go Authors and the Public Suffix List by Mozilla under MPL v2.0. The repository carries LICENSE.MIT and LICENSE.MPLv2.0, and there is a genlicenses.sh script plus a licenses directory. If you redistribute mox or a modified binary, the bundled third-party terms travel with it, so check the generated license output rather than assuming MIT covers everything in the tree.

Ongoing cost is mostly DNS and certificates. Automatic TLS handles the certificate side through ACME. DNS records, DKIM keys and DANE material are manual until the roadmap items land, so budget for periodic checks of SPF, DKIM, DMARC and MTA-STS records. Prometheus metrics and structured logging are the operational hooks you have for watching delivery and reputation behaviour.

## Conclusion

Adopt mox if you control a dedicated (virtual) machine, can add the DNS records the quickstart prints, and want SMTP, IMAP, webmail and TLS from one Go binary rather than a stack of daemons. Do not adopt it if you must keep an existing webserver on ports 80 and 443, if you need a Windows server (the README states mox serve does not yet work there), or if you need the roadmap items (JMAP, CalDAV, encrypted storage) today. Before committing, verify that your DNS provider can publish the records quickstart prints, that your resolver validates DNSSEC, and that port 25 is reachable from the machine. Then run mox quickstart and read the generated mox.conf and domains.conf.

## FAQ

### What is SMTP and what is it used for?

SMTP is the protocol mox uses for receiving, submitting and delivering email, and the README lists it with extensions as a core feature. In mox it listens on port 25 for incoming delivery, 465 for submission with TLS, and 587 for submission without initial TLS.

### What is a self-hosted mail client?

Mox is a mail server rather than a client: it exposes IMAP4 with extensions on ports 993 and 143 so ordinary mail clients can read and send mail, and it also ships webmail for reading and sending from the browser. The README notes that account autodiscovery exists through SRV records, Microsoft-style and Thunderbird-style records, and Apple device management profiles, but that client support is limited.

### Is SMTP still used today?

Mox is built around it. The README lists SMTP with extensions for receiving, submitting and delivering email, plus DANE and MTA-STS for inbound and outbound delivery over SMTP with STARTTLS, including REQUIRETLS and incoming and outgoing TLSRPT reporting.

### How do I fix my email SMTP server?

The mox material does not describe a repair procedure, but it does describe where to look: the web admin interface shows status information and lets you modify the configuration file, and mox exposes Prometheus metrics on port 8010 plus structured logging. The README also suggests checking the DNS records the quickstart prints, since SPF, DKIM, DMARC, MTA-STS and TLS validation depend on them.

## Sources

- [License: MIT](https://github.com/mjl-/mox/blob/main/LICENSE)
- [mjl-/mox on GitHub](https://github.com/mjl-/mox)
- [Project website](https://www.xmox.nl)
- [README](https://github.com/mjl-/mox/blob/main/README.md)
- [Releases](https://github.com/mjl-/mox/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mjl-mox
