# smtp4dev: a fake mail server that speaks IMAP as well as SMTP

> The .NET fake SMTP server that grew into a test tool: an IMAP and POP3 endpoint, HTML compatibility reports, session logs, scripting and a terminal UI. Useful when your mail integration needs more than an inbox that captures messages.

**rnwood/smtp4dev** — smtp4dev - the fake smtp email server for development and testing

- Repository: https://github.com/rnwood/smtp4dev
- Stars: 3,995 · Forks: 428
- Language: C#
- License: BSD-3-Clause
- Published: 2026-10-08 · Updated: 2026-10-08 · Language: en
- Canonical page: https://hysenlabs.com/projects/rnwood-smtp4dev

## Why an IMAP server matters more than another inbox

Most fake SMTP servers do one thing: accept a message and show it in a web UI. smtp4dev also serves IMAP and POP3, which is the feature that separates it from that category. If your application reads mail back, synchronises a mailbox, or tests anything that logs in with credentials before it can send, a capture-only server leaves a real gap in the test. You end up mocking the retrieval path, and mocks are exactly where email bugs hide.

The repository layout backs this up. `smtpserver/` and `imapserver/` are separate top-level directories, so the two protocols are distinct components rather than a bolt-on. TLS is available in both implicit and STARTTLS modes with automatic self-signed certificate generation, and authentication is supported, which together let you simulate a provider that rejects unauthenticated relay.

The README also lists multiple mailboxes with rules controlling which message goes where. That matters when a system sends different templates to different recipients and you want to prove each landed in the right mailbox instead of a single catch-all.

## Reading the comparison table for what it is

The README spends a long stretch on a feature matrix against MailHog, MailCatcher, MailDev and FakeSMTP, and it is worth being clear about what that table is and is not. Each of the fourteen numbered footnotes points at the other project's own documentation, so the claims are sourced rather than invented, which is unusual and to the project's credit. It is still a self-assessment: a project marking its own column is the right way to read it.

The pattern in the table is consistent. MailHog, MailCatcher and MailDev all give you a basic web interface, an SMTP listener and a REST API. None of them ship an IMAP server, an HTML compatibility report, a MIME parts inspector, SMTP session logging or scripting with error simulation. MailHog has a Chaos Monkey facility for failure testing, which is the closest equivalent, and MailDev is the only one of the three with any responsive-preview support.

One inconsistency is worth naming. The opening description hedges the platform support as Windows, Linux, Mac OS-X and maybe elsewhere where .NET Core is available, while the table asserts cross-platform on .NET 10 without hedging. The current `README.md` and the three `Dockerfile.linux` variants suggest the stronger claim is the accurate one now, but the prose above it was written for an earlier runtime.

## Publishing the ports that matter, and not more

The repository ships a `docker-compose.yml` and three Linux Dockerfiles, including an ARM64 build, so container use is a first-class path rather than an afterthought. The compose file maps the web interface and three mail ports, and it also carries an in-file warning that the defaults publish to every network interface:

```yaml
    ports:
      - '5000:80'
      - '25:25'
      - '143:143'
      - '110:110'
```

Those four numbers are the whole API surface for most users. Port 5000 is the web UI, 25 is SMTP, 143 is IMAP and 110 is POP3. Point your application's mail settings at localhost and the same ports, or at `mailpit`-style container addressing if you are on a shared network.

The file also documents the fix, which is a prefix rather than a flag: adding `127.0.0.1:` before each mapping restricts the service to the loopback interface. State lives in a named volume mounted at `/smtp4dev`, so messages survive a container restart.

## Inspecting mail the way you would on a real provider

The web interface is where most of the time goes. The README's screenshot sections describe a message list showing sender, recipient, subject and timestamps, a detail view that renders HTML with a viewport size switcher for simulating mobile, and a raw source view with syntax highlighting and line numbers.

The raw source view is the one that saves hours. When an application produces a malformed multipart message, the MIME parts inspector and the line-numbered source let you see the boundary it actually emitted rather than guessing what the library did. Combined with the multipart MIME inspector listed among the features, this covers the class of bug where the message is technically accepted by a capture server and would be rejected by a stricter provider.

The HTML compatibility report is the least common feature here. It reports which HTML and CSS features are supported across different email clients, and the README pairs it with HTML validation. Whether it is accurate depends on how current its client data is, which the repository does not document on this page, so treat the report as a second opinion alongside a real client test rather than as ground truth.

## Session logs, scripting and a terminal UI

SMTP session logging is what you read when the message never arrives at all. The README describes detailed session logs for debugging delivery issues and protocol interactions, which is the answer to a class of failure that has nothing to do with your mail template: authentication rejected, TLS negotiation failed, size limit exceeded.

Scripting expressions extend that into simulation. The feature list includes error simulation through scripting, so a test can make the server reject a specific address or return a chosen SMTP code. That is materially different from asserting on captured messages, because it exercises your retry and error-handling code against a server that is genuinely refusing.

The terminal user interface is listed as full functionality in TUI mode, which is a departure from every alternative in the comparison table. For a headless environment such as a container or an SSH session, that removes the dependency on a browser, and the same `AGENTS.md` and `.devcontainer/` files at the repository root suggest the project is set up for agent-assisted work on itself. Dark mode is also listed, which is not a technical feature but does suggest someone uses this tool at night.

## Release naming and documentation boundaries

The recent releases are named `3.16.0-ci20260921100_pr2099`, `3.16.0-ci20260915102_pr2097` and `3.16.0-ci20260915101_pr2099`, published between 2026-09-15 and 2026-09-21. These are continuous integration previews built per pull request, and each release body is the same installation table linking Winget packages and standalone archives. There is no changelog prose in them. If you are tracking smtp4dev for release notes, you will find the interesting detail in pull requests and issues instead, with 26 currently open.

The README itself is a front page with links, not a manual. Installation, configuration, client setup and the API all live under `docs/`, with dedicated pages for `Installation.md`, `Configuration.md`, `Configuring-Clients.md`, `API.md` and `Docker-Security.md`. Anything you want to know about a specific setting will be in the configuration document, and the API page is where the OpenAPI and Swagger surface is described.

One historical note helps when you search: the README points older Windows-only GUI users to v2.0.10, which is a separate download. The v3 line you would install today is the cross-platform one, and the two are not the same program in different clothes.

## Conclusion

smtp4dev is worth the extra surface area when your application fetches mail over IMAP, signs in before sending, or needs to see exactly what a client put on the wire. MailHog or MailDev remain the faster answer for the common case of capturing an outbound message and asserting on it. Before adopting it, read docs/Docker-Security.md and bind every published port to 127.0.0.1, because the shipped compose file exposes all interfaces by default. Then install from the Winget package or the Linux Dockerfiles rather than a CI preview tag, since the recent releases are named like 3.16.0-ci20260921100_pr2099 rather than a clean version number.

## FAQ

### How do I install smtp4dev?

The README links to installation docs and the recent releases publish Winget packages plus standalone archives and Linux Docker builds. The shipped docker-compose.yml maps the web interface to port 5000 and the SMTP, IMAP and POP3 services to ports 25, 143 and 110, so a container start is usually enough to have a working fake mail server.

### What makes smtp4dev a good fake SMTP server for testing?

Beyond capturing messages in a web UI, it serves IMAP and POP3 so you can test mailbox retrieval and authentication, logs SMTP sessions for protocol debugging, and supports scripting expressions for error simulation. It also renders HTML with a viewport switcher and produces HTML compatibility reports, which MailHog, MailCatcher and MailDev do not.

### Which ports does smtp4dev listen on?

The docker-compose.yml publishes four: 5000 for the web interface, 25 for SMTP, 143 for IMAP and 110 for POP3. It also stores message data in a named volume mounted at /smtp4dev, and any configuration override uses double-underscore environment keys such as ServerOptions__BasePath.

## Sources

- [Issues](https://github.com/rnwood/smtp4dev/issues)
- [License: BSD-3-Clause](https://github.com/rnwood/smtp4dev/blob/master/LICENSE)
- [README](https://github.com/rnwood/smtp4dev/blob/master/README.md)
- [Releases](https://github.com/rnwood/smtp4dev/releases)
- [rnwood/smtp4dev on GitHub](https://github.com/rnwood/smtp4dev)

---

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