A fast, self-hosted SMTP mail catcher for development and testing.
Capture outbound email, inspect it in a modern UI, and assert on it in CI.
Documentation · API Reference · Docker Hub
docker run -p 1025:1025 -p 8025:8025 smyile/rustmail:latestPoint your app's SMTP at localhost:1025, then open localhost:8025. Emails appear in real time.
services:
rustmail:
image: smyile/rustmail:latest
ports:
- "1025:1025"
- "8025:8025"
volumes:
- rustmail-data:/data
restart: unless-stopped
volumes:
rustmail-data:brew install rustmailapp/rustmail/rustmailWarning
AUR account registration has been closed since June 2026, so we have no way
to publish or update rustmail-bin. Whatever this command installs is not a
release we publish or keep current. Prefer Homebrew, Docker, or the
pre-built binaries.
yay -S rustmail-bingit clone https://github.com/rustmailapp/rustmail
cd rustmail && make buildDownload from GitHub Releases: Linux x86_64/aarch64/armv7 (glibc and musl builds), macOS (Intel + Apple Silicon), and multi-arch Docker images.
RustMail 0.8 stores messages in a new database layout. On first start it migrates an existing database automatically, before SMTP and HTTP start (about 4 s per 100k small messages), and keeps the old file as rustmail.db.schema0.bak until you delete it. You need free disk for the old and the new file side by side.
To go back, run rustmail restore-backup with the new binary before installing the older version; mail received after the upgrade stays only in the new file. Older binaries refuse an upgraded database without writing to it. See the upgrade guide for details, including Docker and Homebrew.
| Feature | Description |
|---|---|
| Persistent storage | SQLite-backed, emails survive restarts. --ephemeral for CI. |
| Full-text search | FTS5 across subject, body, sender, and recipients. |
| Real-time UI | WebSocket push: new email appears instantly. Dark/light mode, keyboard shortcuts. |
| CI-native | REST assertion endpoints, CLI assert mode, and a first-party GitHub Action. |
| Single binary | Frontend embedded at compile time. ~7 MB, zero runtime dependencies. |
| Auth header display | Parses DKIM, SPF, DMARC, and ARC headers with color-coded status badges. |
| Webhooks | Fire-and-forget POST on every new message. |
| Email release | Forward captured emails to a real SMTP server. |
| Optional STARTTLS | Advertised on the normal SMTP port when both --smtp-tls-cert and --smtp-tls-key are configured. |
| Export | Download any email as EML or JSON. |
| Retention policies | Auto-purge by age (--retention) or count (--max-messages). |
| TUI | Optional terminal UI client for Neovim and headless workflows. |
- uses: rustmailapp/rustmail-action@v1
- run: npm test # your app sends emails to localhost:1025
- uses: rustmailapp/rustmail-action@v1
with:
mode: assert
assert-count: 1
assert-subject: "Welcome"Run as an ephemeral mail catcher that exits with a status code, for CI without the GitHub Action:
rustmail assert --min-count=2 --subject="Welcome" --timeout=30sConfigure via CLI flags, RUSTMAIL_* environment variables, or a TOML config file:
rustmail serve --bind 0.0.0.0 --smtp-port 2525 --http-port 9025
rustmail serve --retention 24 --max-messages 1000
rustmail serve --webhook-url https://hooks.example.com/email
rustmail serve --smtp-tls-cert ./certs/localhost.pem --smtp-tls-key ./certs/localhost-key.pemSTARTTLS uses the same SMTP port via explicit upgrade. Both --smtp-tls-cert and --smtp-tls-key are required; setting only one fails startup, and STARTTLS is advertised only when both are set.
See the full configuration reference.
A terminal UI that connects to a running RustMail instance. Also available as a Neovim plugin.
Full docs at docs.rustmail.app:
Licensed under either of:
at your option.


