Transports

Mailpit

Catch outbound email in a local Mailpit instance during development.

Catch outbound email in a local Mailpit instance while you develop. Use it for the welcome email or password-reset flow before you point at a production provider.

The one rule

Use Mailpit only in development — swap to a production transport before you deploy.

Quick start

Start Mailpit (SMTP 1025, UI 8025):

docker run -d --rm -p 1025:1025 -p 8025:8025 axllent/mailpit
import { createMailer } from "sently/mailer";
import { MailpitTransport } from "sently/transports/mailpit";

const mailpit = new MailpitTransport();
const mailer = await createMailer({ transport: mailpit });
await mailer.send({
  from: "dev@example.com",
  to: "you@example.com",
  subject: "Hello",
  text: "Captured by Mailpit",
});

Open http://localhost:8025, or list messages from code:

const inbox = await mailpit.messages();
console.log(inbox.messages[0]?.Subject);

Configuration

OptionTypeDefaultMeaning
hoststring"localhost"SMTP hostname
portnumber1025SMTP port
securebooleanfalseImplicit TLS on connect
requireTLSbooleanfalseRefuse AUTH without TLS
authSMTPAuthOptional SMTP credentials
tlsTLSOptionsTLS options when TLS is enabled
connectionTimeoutnumberSocket connect timeout (ms)
adapterSocketAdapterauto-detectedRuntime TCP adapter
apiUrlstring"http://localhost:8025"Web UI / REST API base
apiAuth{ user, pass }Basic auth for the UI/API

provider is "mailpit". verify() checks SMTP; close() closes the socket adapter.

REST helpers

Vendor extras stay on the transport instance (not on createMailer):

MethodMailpit APIMeaning
messages({ limit?, start? })GET /api/v1/messagesList captured messages (newest first)
getMessage(id)GET /api/v1/message/{id}Full message body
deleteMessages(ids)DELETE /api/v1/messagesDelete by id
deleteAll()DELETE with empty IDsClear the inbox
webUrlUI base URL (same as apiUrl)
await mailpit.deleteAll();
await mailer.send({ from: "a@test.com", to: "b@test.com", subject: "T", text: "ok" });
const list = await mailpit.messages({ limit: 1 });
const full = await mailpit.getMessage(list.messages[0]!.ID);

REST failures throw MailpitError (provider: "mailpit"). Empty getMessage("") throws with status 400.

Troubleshooting

Learn more

  • SMTP — generic SMTP when you are not on Mailpit
  • Preview — write .eml files to disk instead
  • Email channelcreateMailer contract

Next

On this page