Packages

Local SMTP+IMAP email server for dev/test. Drop-in GreenMail wrapper.

Current section

Files

Jump to
greenmail README.md
Raw

README.md

# GreenMail
Local SMTP+IMAP email server for Elixir dev/test environments. Wraps [GreenMail](https://greenmail-mail-test.github.io/greenmail/) — catches **all** outbound email at the SMTP level. No emails leave your machine. Ever.
## Why not Swoosh.Adapters.Local?
Because it only catches emails sent through Swoosh. If your app talks SMTP directly (a `SmtpClient`, a background mailer, a third-party library), Swoosh.Local never sees those messages. GreenMail catches everything — it's a real SMTP server listening on localhost.
## Setup
### 1. Add dependency
```elixir
# mix.exs
defp deps do
[
{:greenmail, "~> 0.1", only: :dev}
]
end
```
### 2. Install the JAR
```bash
mix greenmail.install
```
Downloads `greenmail-standalone.jar` to `~/.greenmail/`. One download, shared by all projects.
**Requires:** Java 17+ (`brew install openjdk` on macOS)
### 3. Add to supervision tree (dev only)
```elixir
# application.ex
def start(_type, _args) do
children = [
# ... your children ...
] ++ greenmail_children()
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
defp greenmail_children do
if Application.get_env(:my_app, :greenmail, false) do
[{GreenMail.Server, [supervisor: MyApp.Supervisor]}]
else
[]
end
end
```
```elixir
# config/dev.exs
config :my_app, greenmail: true
```
### 4. Point SMTP at GreenMail
Any SMTP config pointing at `localhost:3025` will be caught. For IMAP ingestion, use `localhost:3143`.
Auth is disabled — any username/password works and auto-provisions a mailbox for that address.
## API
```elixir
GreenMail.running?() # => true
GreenMail.status() # => {:ok, %{smtp_port: 3025, imap_port: 3143, os_pid: 12345, ...}}
GreenMail.stop() # Stop server, free ports
GreenMail.start() # Restart after stop
GreenMail.restart() # Flush all mailboxes
```
## Ports
| Protocol | Port |
|----------|------|
| SMTP | 3025 |
| IMAP | 3143 |
## How it works
- GenServer starts GreenMail JAR as an Erlang port process
- Java process dies when your app dies — no orphans
- Per-address mailboxes: email to `alice@example.com` lands in that IMAP inbox
- In-memory only: emails vanish on restart
- If ports are already in use, assumes external mail server and skips startup
## Reading caught emails
Use any IMAP client. From Elixir, you can use `:gen_smtp` or `Mail`:
```elixir
# The email sent to alice@example.com is in that address's IMAP inbox
# Login: alice@example.com / any-password
# Host: localhost, Port: 3143, SSL: off
```
Or just use a mail client (Thunderbird, etc.) pointed at localhost:3143.
## License
MIT