Home/Email API/Node.js send email

Node.js send email

Node.js sends email through a library that speaks SMTP, most commonly Nodemailer. There is no mail transport in the standard library, so this is a dependency rather than a built-in.

VerifiedBy Kam Low, Co-founder·Updated

Install the library

Nodemailer installs from npm and has no runtime dependencies of its own, which is part of why it became the default choice.

Verified against npm
zero runtime dependencies Node 18+ fully typed
The entry-point split
nitrosendOne package
root exportserver only, holds the secret key
nitrosend/browserthe export meant for client code
Dependencies, runtime, types: table stakes. The export split is what keeps the secret key off the client.

It supports both SMTP and a pluggable transport interface, so the same calling code can target a provider's HTTP API through a transport plugin instead of SMTP.

Implementation

The working sequence is two steps. Create a transporter with the host, port, security flag and authentication object. Call sendMail with an options object holding from, to, subject, and either text or html.

The secure flag is the setting people get wrong. Set to true it opens an implicit TLS connection, which pairs with port 465. The false value instead starts in the clear and upgrades through STARTTLS, which is the port 587 path. Pairing secure: true with port 587 produces a connection that hangs rather than returning a usable error.

Set both text and html when sending HTML. Nodemailer assembles the multipart message, and the plain-text part is what some clients render and what filters treat more favourably.

sendMail returns a promise resolving to an info object containing the message ID and the server's accepted and rejected recipient arrays. A send can resolve successfully while individual recipients were rejected, so checking info.rejected matters when sending to more than one address.

Reuse a transporter across sends rather than creating one per message. Each new transporter opens a fresh connection, and providers limit concurrent connections per account.

Run the script

Running the file executes the send. Because sendMail is asynchronous, an unhandled rejection exits silently in older Node versions, so wrap the call in try/catch or attach a catch handler.

Credentials belong in environment variables rather than the source file. A committed application password is a live sending credential for the mailbox that issued it.

Common provider configuration

Gmail uses smtp.gmail.com on port 587 with STARTTLS or 465 with implicit TLS. Google blocks ordinary account passwords for third-party clients, so an app password generated against an account with two-step verification is required.

Microsoft 365 uses smtp.office365.com on port 587 with STARTTLS, documented in Microsoft's settings reference. Basic authentication on this path is scheduled for deprecation in favour of OAuth, which Nodemailer supports through an OAuth2 auth object.

Both are mailbox providers, and both apply per-mailbox sending limits sized for a person rather than an application. Microsoft documents 10,000 recipients per day and 30 messages per minute on client submission.

For application volume the alternative is a submission service authenticating as your own verified domain, reached either over SMTP with issued credentials or through an HTTP API. Nitrosend's integration surface is a REST API, an MCP server and a CLI, with no published Node SDK, so integration there is an ordinary HTTP request rather than a package install.

The official package, and the split that matters

There is one official package for Node and TypeScript, and it is the exception to the REST-only rule that applies to every other language. It is fully typed, ships with zero runtime dependencies, and requires Node 18 or later.

Zero dependencies is a deliberate property rather than a boast. An email SDK sitting in a dependency tree with a dozen transitive packages is a supply-chain surface attached to a credential that can send as your domain, so the smaller that surface the better.

Most consequential is the split between server and browser entry points. The main export is a server SDK for Node, edge functions or any backend, and it takes a secret key with full account access. The package also publishes a separate browser entry, and the distinction is not cosmetic: a secret key must never reach a browser bundle, and having two entry points is what makes that boundary explicit rather than a matter of discipline.

Worth knowing that raw HTTP is still a first-class option. Our own REST guide's JavaScript examples use plain fetch, and there is nothing second-class about that: the package calls the same API, and the same key authenticates both, so the choice is about typing convenience rather than capability.

None of that split, the typed errors, the zero dependencies, is really the point. The point is you don't have to write any of it. Tell Claude, Cursor, or Codex to send the email, and our MCP server composes it, picks the transport, and sends, with you approving before anything leaves. Email marketing is moving from developers wiring up SDKs to agents doing the wiring, and Nitrosend is the option built for that shift, which is why we're a listed app in the ChatGPT app marketplace rather than just another package on npm.

Go deeper

Email API

First send in thirty seconds.

Simple pricing. Unlimited contacts.

Every plan includes full stack emailing: Flows, Newsletter Campaigns and Transactional Email, plus our NitroWheel LLM and all agent integrations (Claude, ChatGPT, Codex, Cursor and others). Pay for what you send, not who you store.

Free
$0
forever
  • Emails 8,000then 500/mo
  • Email types Transactional & Marketing
  • AI actions 20/mo
  • Contacts Free & Unlimited
  • Brands 3 · Custom domain 1
  • Seats 1
  • Recipients / rolling 24h 100–5,000
  • Email validation Prepaid only
Start free
Ultra
$100
per month
  • Emails 125,000/month
  • AI actions 5,000/mo
  • Brands 10 · Domains 10
  • Seats 10
  • Frontier AI Included
  • Dedicated IP Available
  • Recipients / rolling 24h 1,000–625,000
  • Email validation Prepaid only
Get started
Enterprise
$300
per month
  • AI actions Unlimited
  • Unlimited brands & domains Included
  • SSO / SAML Included
  • 99.9% SLA Included
  • Recipients / rolling 24h Contracted
  • Email validation Prepaid only
Get started

Daily allowances depend on your plan and sender standing. Strong list, domain and delivery evidence can raise standing, including on day one. Trusted receives the full plan allowance; available email credits, safety checks and delivery pacing still apply.

Free forever. No credit card required. See full comparison →