Get started

Migrate from Nodemailer

Move SMTP configuration and message fields to sently incrementally.

Keep your welcome email, receipt, or password-reset fields (from, to, subject, text / html). Replace createTransport with createSMTPMailer, rename sendMail to send, and await the factory before the first send.

The one rule

Use createSMTPMailer for relay host/port/auth. Use createMailer only when you already have an explicit transport.

Quick start

import { createSMTPMailer } from "sently/smtp";

const mailer = await createSMTPMailer({
  host: "smtp.example.com",
  port: 587,
  auth: { user: "user@example.com", pass: process.env.SMTP_PASSWORD! },
});
- const info = await transporter.sendMail({
+ const result = await mailer.send({
    from: "Acme <hello@example.com>",
    to: "person@example.com",
    subject: "Welcome",
    text: "Thanks for joining.",
  });
console.log(result.messageId, result.accepted, result.rejected);

API map

Nodemailersently
createTransport({ host, port, auth })await createSMTPMailer({ host, port, auth })
transporter.sendMail(msg)mailer.send(msg)
transporter.verify()mailer.verify()
transporter.close()mailer.close()
info.messageId / accepted / rejected / response / envelopeSame fields on SendResult
HTTP providers via plugins / customcreateMailer + sently/transports/<provider>

Message fields

Nodemailersently
from / to / cc / bcc / replyToSame names on MailOptions
subject, text, html, headers, messageId, dateSame names
priority"high" | "normal" | "low"
attachments[].filename / content / path / contentTypeSame names
attachments[].cidattachments[].contentId
attachments[].contentDisposition: "inline"attachments[].inline: true
icalEvent, SOCKS proxy optionsNot supported — see Non-goals

SMTP options

OptionTypeDefaultMeaning
hoststringrequiredRelay hostname
portnumber587 (465 if secure)SMTP port
securebooleanfalseImplicit TLS on connect
authSMTPAuth{ user, pass?, type?, oauth2? }
poolbooleanfalseConnection pooling
requireTLSbooleantrue when auth is setRefuse AUTH on a cleartext connection
tlsTLSOptionsrejectUnauthorized, servername, minVersion
connectionTimeoutnumberSocket connect timeout (ms)
greetingTimeoutnumberWait for SMTP greeting (ms)
socketTimeoutnumberIdle socket timeout (ms)

Switch to an HTTP provider later

Keep mailer.send and change only construction:

- import { createSMTPMailer } from "sently/smtp";
- const mailer = await createSMTPMailer({ host, port, auth });
+ import { createMailer } from "sently/mailer";
+ import { ResendTransport } from "sently/transports/resend";
+ const mailer = await createMailer({
+   transport: new ResendTransport({ apiKey: process.env.RESEND_API_KEY! }),
+ });

Consequence: message fields stay the same; only the factory and transport change.

Troubleshooting

Learn more

Next

On this page