Skip to main content

SMTP transport

SMTP is the main transport in Nodemailer for delivering messages. SMTP (Simple Mail Transfer Protocol) is also the standard protocol that email servers use to communicate with each other, making it truly universal. Almost every email delivery provider supports SMTP-based sending, even when they primarily advertise API-based sending. While APIs may offer additional features, they also create vendor lock-in. With SMTP, you can switch providers by simply changing your configuration object or connection URL.

Creating a transport

To send emails via SMTP, create a transporter object by calling nodemailer.createTransport():

const nodemailer = require("nodemailer");

const transporter = nodemailer.createTransport(options[, defaults]);
  • options - an object that defines the SMTP connection settings (detailed in the sections below).
  • defaults - an optional object whose properties are merged into every message you send. This is useful for setting a common from address or other repeated values.

Instead of an options object, you can also pass a connection URL. Use the smtp: protocol for standard connections or smtps: for connections that use TLS from the start (typically port 465). The URL can also be supplied as the url property of the options object, in which case the remaining options are merged with the parsed URL values.

// Pooled connection via TLS
const transporter = nodemailer.createTransport(
"smtps://username:password@smtp.example.com/?pool=true"
);

You can pass any top-level transport option (and tls.* sub-options, e.g. tls.rejectUnauthorized=false) as a query parameter in the URL; other nested options are ignored:

ParameterExampleDescription
poolpool=trueEnable connection pooling
maxConnectionsmaxConnections=5Maximum simultaneous pool connections
maxMessagesmaxMessages=100Messages per connection before reconnecting
serviceservice=gmailUse a well-known service preset

General options

NameTypeDefaultDescription
hoststring"localhost"The hostname or IP address of the SMTP server to connect to.
portnumber587 (465 if secure: true)The port number to connect to.
securebooleanfalse (auto-true for port 465)If true, the connection uses TLS immediately upon connecting. Set this to true when connecting to port 465 (if secure is left unset and port is 465, it defaults to true automatically). For port 587 or 25, leave this as false and let STARTTLS upgrade the connection.
servicestring--A shortcut to configure well-known email services like "gmail" or "outlook". When set, this overrides host, port, and secure with predefined values. See the well-known services list.
authobject--Authentication credentials (see Authentication below).
authMethodstringfirst advertised methodThe preferred SASL authentication method. Common values include "PLAIN", "LOGIN", and "CRAM-MD5". If unset, the first method advertised by the server is used (falling back to "PLAIN").
customAuthobject--A map of custom SASL mechanism names to handler functions. See Custom authentication.
urlstring--Connection URL (same syntax as the string form of createTransport()); other options are merged with the parsed URL values.
info

When you specify a hostname, Nodemailer resolves it using DNS before connecting (falling back to the OS resolver, which also consults /etc/hosts). If you use an IP address as host, you should also set tls.servername to the server's hostname so TLS certificate validation works correctly.

TLS options

NameTypeDefaultDescription
securebooleanfalse (auto-true for port 465)See General options above.
tlsobject--Additional options passed directly to Node.js TLSSocket. For example, { rejectUnauthorized: false } to accept self-signed certificates.
tls.servernamestring--The hostname to use for TLS certificate validation. Required when host is set to an IP address. Can also be set as a top-level servername option outside the tls object.
ignoreTLSbooleanfalseIf true, Nodemailer will not use STARTTLS even if the server advertises support for it. The connection remains unencrypted.
requireTLSbooleanfalseIf true, Nodemailer requires a STARTTLS upgrade. If the server does not support STARTTLS, sending fails with an error.
info

Setting secure: false does not mean your emails are sent unencrypted. Most modern SMTP servers support STARTTLS, which upgrades an unencrypted connection to an encrypted one after connecting. Nodemailer automatically uses STARTTLS when available, unless you explicitly disable it with ignoreTLS: true.

Connection options

NameDefaultDescription
namelocal hostnameThe hostname sent in the EHLO (or HELO) greeting. The server uses this to identify your client. Defaults to your machine's hostname if it is a fully-qualified domain name; otherwise [127.0.0.1] is used.
localAddress--The local network interface to bind when making the connection. Useful when your machine has multiple network interfaces.
connectionTimeout120000 msHow long to wait (in milliseconds) for the TCP connection to be established before giving up.
greetingTimeout30000 msHow long to wait (in milliseconds) for the server to send its initial greeting after the connection is established.
socketTimeout600000 msHow long a connection can remain idle (in milliseconds) before Nodemailer closes it. The default is 10 minutes.
dnsTimeout30000 msMaximum time (in milliseconds) to wait for DNS lookups to complete.
dnsTtl300000 msDNS lookup results are cached for 5 minutes. This TTL is currently not configurable for the SMTP transport.
lmtpfalseIf true, use the LMTP (Local Mail Transfer Protocol) instead of SMTP. LMTP is typically used for local mail delivery.
opportunisticTLSfalseIf true, Nodemailer continues with an unencrypted connection when STARTTLS upgrade fails, instead of aborting.
forceAuthfalseIf true, attempt authentication even when the server does not advertise AUTH capability. Some misconfigured servers require this.
allowInternalNetworkInterfacesfalseIf true, internal (loopback) network interfaces are also counted when Nodemailer determines whether the machine supports IPv4/IPv6 lookups. By default, an address family is only resolved if the machine has at least one non-internal interface of that family (relevant for offline or loopback-only environments).

Debug options

NameTypeDescription
loggerobject / booleanSet to true to enable console logging, or pass a Bunyan-compatible logger instance for custom logging. Set to false or leave unset to disable logging.
debugbooleanIf true, logs the raw SMTP protocol traffic (commands and responses) and the transmitted message content. When false, only high-level transaction events are logged.
transactionLogbooleanIf true, logs SMTP commands and responses like debug, but without the message content — lighter logging suitable for production.
componentstringThe component name used in log output (e.g., 'smtp-transport', 'smtp-pool'). Useful when running multiple transporters to identify which one generated a log entry.

Custom logger

If you want to use a logging library like Pino or another custom logger, you can wrap it in a Nodemailer-compatible logger object. The logger should implement methods for each log level: trace, debug, info, warn, error, and fatal; if a level method is missing, Nodemailer falls back to another available level method instead of throwing.

const smtpLogger = {};

// Set up logger wrapper for each log level
for (let level of ['trace', 'debug', 'info', 'warn', 'error', 'fatal']) {
smtpLogger[level] = (data, message, ...args) => {
if (args && args.length) {
message = util.format(message, ...args);
}
data.msg = message;
data.src = 'nodemailer';
if (typeof pinoLogger[level] === 'function') {
pinoLogger[level](data);
} else {
pinoLogger.debug(data);
}
};
}

nodemailer.createTransport({
// ... other options
logger: smtpLogger
})

Security options

These options restrict how Nodemailer handles attachments and content sources:

NameTypeDescription
disableFileAccessbooleanIf true, prevents Nodemailer from reading attachment content from the filesystem (paths like /path/to/file.pdf).
disableUrlAccessbooleanIf true, prevents Nodemailer from fetching attachment content from URLs (like https://example.com/file.pdf).

Pooling options

Connection pooling keeps multiple SMTP connections open to send messages faster. See Pooled SMTP for the complete list of pooling options. The most important option is:

NameTypeDescription
poolbooleanIf true, enables connection pooling. Pooled connections are reused for multiple messages.

Proxy options

You can route SMTP connections through HTTP or SOCKS proxies. Read more in Using proxies.

Examples

1. Single connection

This is the simplest configuration. A new SMTP connection is created for each message you send. The connection starts unencrypted but is automatically upgraded via STARTTLS if the server supports it.

const transporter = nodemailer.createTransport({
host: "smtp.example.com",
port: 587,
secure: false, // Start unencrypted, upgrade via STARTTLS
auth: {
user: "username",
pass: "password",
},
});

2. Pooled connections

For better performance when sending multiple messages, use connection pooling. This keeps connections open and reuses them, avoiding the overhead of establishing a new connection for each message.

const transporter = nodemailer.createTransport({
pool: true,
host: "smtp.example.com",
port: 465,
secure: true, // Use TLS from the start (required for port 465)
auth: {
user: "username",
pass: "password",
},
});

3. Allow self-signed certificates

In development environments or internal networks, you may need to connect to servers using self-signed certificates. Disable certificate validation with rejectUnauthorized: false. Note that this reduces security and should not be used in production.

const transporter = nodemailer.createTransport({
host: "my.smtp.host",
port: 465,
secure: true,
auth: {
user: "username",
pass: "password",
},
tls: {
// Accept self-signed or invalid certificates
rejectUnauthorized: false,
},
});

Authentication

Most SMTP servers require authentication before accepting messages. Nodemailer supports several authentication methods.

If you omit the auth object entirely, Nodemailer attempts to send without authentication. This works only with servers that allow unauthenticated sending (typically internal relay servers).

const transporter = nodemailer.createTransport({
host: "smtp.example.com",
port: 587,
});

Login

The most common authentication method uses a username and password. Nodemailer automatically selects a mechanism supported by the server (preferring PLAIN, then LOGIN, then CRAM-MD5); use the authMethod option to force a specific one.

auth: {
type: "login", // Optional, this is the default
user: "username",
pass: "password",
}

OAuth 2.0

For services like Gmail or Outlook that support OAuth 2.0, you can authenticate using an access token instead of a password. This is more secure because you do not need to store your password.

auth: {
type: "oauth2",
user: "user@example.com",
accessToken: "generated_access_token",
expires: 1484314697598, // Token expiration timestamp in milliseconds
}

See the dedicated OAuth 2.0 guide for complete setup instructions, including how to automatically refresh tokens. If you need to use an authentication protocol that Nodemailer does not support natively, you can implement a custom authentication handler (see the NTLM handler for an example).

Verifying the configuration

Before sending your first email, you can test whether your SMTP configuration is correct using transporter.verify(). This method attempts to connect to the server and authenticate without sending any message.

// Using async/await
try {
await transporter.verify();
console.log("Server is ready to take our messages");
} catch (err) {
console.error("Verification failed", err);
}

// Using callbacks
transporter.verify((error, success) => {
if (error) {
console.error(error);
} else {
console.log("Server is ready to take our messages");
}
});

The verify() method tests DNS resolution, the TCP connection, TLS upgrade (if applicable), and authentication. However, it does not verify whether the server will accept messages from a specific sender address - that can only be determined when you actually send a message, and depends on the server's policies.