# Stalwart: a Rust mail and collaboration server that speaks IMAP, JMAP, SMTP, CalDAV and CardDAV

> Stalwart bundles mail, calendars, contacts and file storage into one Rust server with pluggable storage backends. It suits operators who want a single deployment instead of a stack of separate daemons, and it is a poor fit for anyone unwilling to own DNS and deliverability.

**stalwartlabs/stalwart** — All-in-one Mail & Collaboration server. Secure, scalable and fluent in every protocol (IMAP, JMAP, SMTP, CalDAV, CardDAV, WebDAV).

- Repository: https://github.com/stalwartlabs/stalwart
- Website: https://stalw.art
- Stars: 14,877 · Forks: 966
- Language: Rust
- License: not declared
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/stalwartlabs-stalwart

## What Stalwart replaces, and for whom

A conventional mail deployment is a pile of daemons: an SMTP server, an IMAP server, a spam filter, a calendar service, a contacts service, and a web file store, each with its own configuration format and its own upgrade path. Stalwart's README describes it as an "all-in-one Mail & Collaboration server" and lists IMAP4rev2 and IMAP4rev1, POP3, SMTP with DMARC, DKIM and SPF, CalDAV with scheduling, CardDAV, WebDAV and the JMAP family of protocols in one server. The intended audience is the operator who would rather run one process than six, and who is comfortable with a configuration surface that reflects that breadth.

The protocol list is the selling point and also the scope warning. JMAP for Mail, JMAP for Calendars, JMAP for Contacts and JMAP for File Storage are all listed, alongside the older DAV protocols for clients that do not speak JMAP yet. If your users are on Thunderbird, Apple Mail or a mobile client, the DAV and IMAP paths matter; if you are building a new client, JMAP is the modern interface. Stalwart supports both from the same server, which is the practical reason to consider it over assembling separate components.

## The crate layout behind the single binary

The workspace in Cargo.toml is the clearest map of how the server is put together. Protocol implementations live in their own crates: crates/imap, crates/imap-proto, crates/smtp, crates/pop3, crates/jmap, crates/jmap-proto, crates/managesieve, crates/dav, crates/dav-proto. Storage is isolated in crates/store, coordination in crates/coordinator, directory lookups in crates/directory, and configuration in crates/registry. Spam handling has crates/spam-filter and crates/nlp. The binary itself is crates/main.

That separation matters when you evaluate the project. A bug in SMTP parsing is unlikely to touch the CalDAV code path, and the storage layer is abstracted behind one crate that the README says can be backed by RocksDB, FoundationDB, PostgreSQL, mySQL, SQLite, S3-compatible object storage, Azure or Redis. The Dockerfile confirms this at build time: it compiles the stalwart package with the feature list "sqlite postgres mysql rocks s3 redis azure nats enterprise", so those backends are selectable at compile time rather than bolted on. Full-text search is a separate concern again, offered through a built-in engine or via Meilisearch, ElasticSearch, OpenSearch, PostgreSQL or mySQL, with the README claiming support for 17 languages.

## Installing Stalwart and sending a first message

The repository ships an install.sh at the top level, and the README links to https://stalw.art/docs/install/get-started for the documented path. The Dockerfile builds a Debian trixie-slim image that creates a stalwart user and group with UID and GID 2000, and prepares /etc/stalwart for configuration and /var/lib/stalwart for data. If you build from source, the workspace targets Rust and the release profile enables LTO with codegen-units set to 1, so expect a long first compile.

The Dockerfile itself is the only container definition in the repository, and it expects the configuration directory and the data directory to be mounted, since the image creates /etc/stalwart and /var/lib/stalwart and runs as the unprivileged stalwart user. Building and running it follows the standard two-step pattern:

```bash
docker build -t stalwart .
docker run -v /etc/stalwart:/etc/stalwart -v /var/lib/stalwart:/var/lib/stalwart stalwart
```

The server reads its settings from /etc/stalwart and stores mail and collaboration data under /var/lib/stalwart, matching the layout the Dockerfile creates. Because the container runs as the unprivileged stalwart user, binding to port 25 requires either granting the capability or fronting the container with a proxy. The README does not document a rollback procedure, so capture the contents of both directories before changing anything.

The first real task after the server is reachable is account and domain setup, which the documentation covers under the same get-started path. Stalwart supports multi-tenancy with domain and tenant isolation, plus aliases, mailing lists, subaddressing and catch-all addresses, so a single deployment can host more than one domain. Before expecting mail to arrive from the wider internet you need working DNS: the README lists automated DNS management, automatic TLS certificate provisioning via ACME, and DANE, MTA-STS and SMTP TLS reporting for transport security. Those are configuration steps on your side, not something the installer performs for you.

## Where the all-in-one design costs you

Running mail is not the same as running a web application. A mail server has to be reachable on port 25, has to present valid TLS, has to publish SPF, DKIM and DMARC records, and has to avoid landing on blocklists. Stalwart gives you the software to do all of that, including DKIM key rotation and management and built-in DMARC, DKIMv2, DKIMv1, SPF and ARC support, but it cannot give you a clean IP reputation. If your hosting provider blocks outbound port 25, which many do by default, nothing in the server configuration fixes that.

The second cost is upgrade risk. The repository contains an UPGRADING directory at the top level, and its existence tells you that moving between versions is a task with its own instructions rather than a drop-in replacement. Releases arrive frequently: v0.16.21 on 2026-09-06, v0.16.22 on 2026-09-13, and v0.16.23 on 2026-09-21. That cadence is healthy for a project, but it means an unattended auto-update is a bad idea for a server holding other people's mail. Read the UPGRADING notes for the version you are moving to before you move.

The third cost is breadth itself. Spam and phishing filtering here includes statistical classifiers, DNSBL checks of IP addresses, domains and hashes, Pyzor collaborative digest filtering, greylisting, spam traps and sender reputation monitoring. Each of those is a knob, and each knob can be set wrong. A small deployment with a handful of mailboxes may find that a dedicated filtering service in front of a simpler SMTP server is less work overall. Stalwart is the right tool when you want the filtering logic to live in the same process as the mail store and you are willing to tune it.

## Alternatives and the real difference in approach

The obvious comparison is a traditional Unix mail stack: Postfix for SMTP, Dovecot for IMAP, and separate services for calendars and contacts. That combination is older, extremely well documented, and has decades of operational experience behind it. Its weakness is exactly what Stalwart targets: four or five configuration formats, four or five upgrade procedures, and no shared identity or storage model between mail and calendar data. Stalwart's answer is one configuration registry and one storage abstraction covering everything, which is a genuine architectural difference rather than a packaging difference.

A second comparison is a hosted mail provider. That removes the deliverability problem entirely, along with the server. The trade-off is that you lose control of the data and the protocol surface: you get whatever IMAP or JMAP endpoints the provider exposes and whatever retention policy it sets. Stalwart's encryption at rest with S/MIME or OpenPGP and its choice of storage backend exist precisely for operators who need that control.

A third option worth naming is running Stalwart only for the collaboration protocols. Nothing in the design forces you to accept inbound SMTP; you can point MX records elsewhere and use the server for IMAP, JMAP, CalDAV, CardDAV and WebDAV. That is a reasonable middle path for teams whose mail already flows through a provider but whose calendars and contacts are stuck in a service they want to leave.

## Licence and the cost of staying current

The README's badge links to the GNU AGPL v3, and the repository carries a LICENSES directory. The project description field here does not state a licence, so treat the README badge as the source. AGPL v3 is a strong copyleft licence with a network clause: if you modify the software and let users interact with it over a network, the licence obliges you to offer them the corresponding source. Running Stalwart unmodified for your own organisation is a different situation from building a modified version into a product you expose to customers. That distinction is worth a conversation with someone qualified to give legal advice, which this article is not.

The ongoing cost is upgrade labour rather than licence fees. Releases land roughly weekly, the UPGRADING directory implies that some of them require manual steps, and the Dockerfile pins a specific Rust toolchain image and a Debian trixie-slim runtime, so a self-built image needs rebuilding when those move. Budget for reading release notes and UPGRADING files on a schedule you choose, not on the schedule the project publishes.

## Conclusion

Adopt Stalwart if you want one Rust process covering mail, calendars, contacts and files, and you are prepared to run the DNS records, TLS certificates and spam filtering that deliverability depends on. Do not adopt it if you need a managed service with a support contract, or if you cannot test an upgrade before applying it, since the repository ships an UPGRADING directory precisely because schema and configuration changes land between releases. Before committing, verify which storage backend your deployment will use, confirm the AGPL v3 licence obligations against how you intend to expose the server, and read the UPGRADING notes for the version you are moving from.

## FAQ

### How do I install Stalwart?

The repository ships an install.sh at the top level, and the README links to the get-started page at stalw.art/docs/install/get-started. A Dockerfile is also provided, building a Debian trixie-slim image that runs as a stalwart user with UID 2000 and uses /etc/stalwart for configuration and /var/lib/stalwart for data.

### How do I set up Stalwart after installing it?

After installation the server reads configuration from /etc/stalwart and stores data under /var/lib/stalwart. You then need working DNS for your domains, since the README lists automated DNS management, ACME certificate provisioning, and DANE, MTA-STS and SMTP TLS reporting as part of transport security.

### Which protocols does Stalwart support?

The README lists JMAP for Mail, Calendars, Contacts and File Storage, IMAP4rev2 and IMAP4rev1 with ManageSieve, POP3, SMTP with DMARC, DKIM and SPF, CalDAV with scheduling, CardDAV and WebDAV. The workspace layout reflects this, with separate crates for imap, smtp, pop3, jmap, dav and managesieve.

### Which storage backends can Stalwart use?

The README lists RocksDB, FoundationDB, PostgreSQL, mySQL, SQLite, S3-compatible object storage, Azure and Redis. The Dockerfile compiles the stalwart package with the feature list "sqlite postgres mysql rocks s3 redis azure nats enterprise", confirming these are selected at build time.

### Is Stalwart free to use?

The README's licence badge links to the GNU AGPL v3 and the repository contains a LICENSES directory. AGPL v3 includes a network clause, so if you modify the software and expose it to users over a network you must offer them the corresponding source.

## Sources

- [Issues](https://github.com/stalwartlabs/stalwart/issues)
- [Project website](https://stalw.art)
- [README](https://github.com/stalwartlabs/stalwart/blob/main/README.md)
- [Releases](https://github.com/stalwartlabs/stalwart/releases)
- [stalwartlabs/stalwart on GitHub](https://github.com/stalwartlabs/stalwart)

---

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