Unable to load comparison data. Please try again later.
Send emails from Node.js – easy as cake! 🍰✉️
See nodemailer.com for documentation and terms.
Nodemailer is developed by the team behind EmailEngine, a self-hosted email API that turns any Gmail, Microsoft 365, or IMAP account into a REST endpoint, with managed OAuth2, webhooks for incoming mail, and built-in sending. If you would rather call an HTTP API than maintain IMAP and SMTP connections yourself, that is what it is for.
Nodemailer targets Node.js 20 and later. The ES module build also runs on Bun (tested against the latest release) and on Cloudflare Workers with the nodejs_compat compatibility flag. On Workers only the SMTP based transports apply, sendmail needs a child process, and the runtime does not allow turning certificate validation off, so tls.rejectUnauthorized: false fails there with an error.
Documentation for Nodemailer can be found at nodemailer.com.
Nodemailer 10 and later require Node.js 20 or newer. The package ships both ES module and CommonJS builds, so import nodemailer from 'nodemailer' and const nodemailer = require('nodemailer') both work. If you need to run on an older Node.js version, stay on the 9.x line.
Gmail either works well, or it does not work at all. It is probably easier to switch to an alternative service instead of fixing issues with Gmail. If Gmail does not work for you, then don't use it. Read more about it here. If the blocker is OAuth2 setup rather than Gmail itself, EmailEngine handles the OAuth2 flow and token refresh for you.
Check your firewall settings. Timeout usually occurs when you try to open a connection to a firewalled port either on the server or on your machine. Some ISPs also block email ports to prevent spamming.
It's either a firewall issue, or your SMTP server blocks authentication attempts from some servers.
secure option. This should be set to true only for port 465. For every other port, it should be false. Setting it to false does not mean that Nodemailer would not use TLS. Nodemailer would still try to upgrade the connection to use TLS if the server supports it.false to skip chain verification or upgrade your Node versionlet configOptions = { host: 'smtp.example.com', port: 587, tls: { rejectUnauthorized: true, minVersion: 'TLSv1.2' } };
Node.js uses c-ares to resolve domain names, not the DNS library provided by the system, so if you have some custom DNS routing set up, it might be ignored. Nodemailer runs dns.resolve4() and dns.resolve6() to resolve hostname into an IP address. If both calls fail, then Nodemailer will fall back to dns.lookup(). If this does not work for you, you can hard code the IP address into the configuration like shown below. In that case, Nodemailer would not perform any DNS lookups.
let configOptions = { host: '1.2.3.4', port: 465, secure: true, tls: { // must provide server name, otherwise TLS certificate check will fail servername: 'example.com' } };
Nodemailer 10 and later are written in TypeScript and ship their own type definitions, so @types/nodemailer is no longer needed and should be removed from your project to avoid conflicting declarations. The type names follow the layout of the old definitions, so references such as Mail.Options, SMTPTransport.Options or Transporter<SMTPTransport.SentMessageInfo> keep compiling, and the most used types (SendMailOptions, Transporter, SentMessageInfo, Attachment, Address) are exported from the package root. For older Nodemailer versions, the community maintained type definitions still apply.
If you are having issues with Nodemailer, then the best way to find help would be Stack Overflow or revisit the docs.
Nodemailer is licensed under the MIT No Attribution license
The Nodemailer logo was designed by Sven Kristjansen.