Most Popular
Courier is a notification service that centralizes all of your templates and messaging channels in one place which increases visibility and reduces engineering time.
Sign-up
Nearly every modern web app needs to send transactional emails in response to user activity — things like account creation, password resets, order confirmations, or verification codes. These emails are essential for keeping users informed and ensuring smooth user experiences.
If you're building with Node.js, there are several ways to implement email delivery. This guide explores three common approaches:
We’ll walk through the pros and cons of each, and include step-by-step code examples so you can choose the best method for your app.
Node.js gives you several options for sending email from your application. In this guide, we’ll compare the three most common approaches:
We’ll break down how each method works, walk through pros and cons, and include hands-on code examples so you can choose the right solution for your stack.
Simple Mail Transfer Protocol (SMTP) is a standard protocol for sending emails across networks. It serves as a relay service that delivers messages from one mail server to another.
When you send an email using a client like Gmail, an SMTP server handles the outgoing message. It communicates with the recipient’s server using SMTP commands, negotiating delivery based on the message headers, destination, and authentication. Most email clients come pre-configured with their own SMTP servers.
🛠️ If you choose to go the SMTP route, use a sandbox service like Mailtrap for safe testing, and make sure your production server is configured with secure defaults.
Email APIs let you send messages from your application through a hosted provider, without needing to run your own mail server. They handle message assembly, delivery, and reputation management on your behalf.
These APIs are ideal when you need a scalable, reliable, and developer-friendly way to send transactional emails — like password resets, receipts, or notifications — with minimal setup.
Popular email API services include:
Most providers offer free or low-cost plans with generous usage limits to get started.
🔍 Before choosing a provider, compare key features, delivery performance, uptime SLAs, and support for your use case.
A notification service like Courier gives you higher-level building blocks to manage notification logic — and lets you reach users across every channel from one place.
You can bring your own provider for each channel. For email, that could be your own SMTP server or a hosted email API like SendGrid, Postmark, or Amazon SES. A notification service can also support failover to alternate providers if one becomes unavailable.
With a notification service, you can add new channels or switch providers without rewriting your app’s business logic. If you need to notify users across email, SMS, push, or chat apps like Slack and WhatsApp — you can do it all from a single platform.
Courier offers a layer of abstraction on top of email APIs — giving you tools for design, orchestration, and observability. You can visually design emails, create delivery rules and workflows, and monitor delivery events in real time — without having to redeploy code.
Some of the key benefits of using a service like Courier:
These features dramatically reduce the engineering effort required to support different notification use cases — and eliminate the need to maintain separate code for each channel or provider.
Another advantage: non-technical teammates can edit content, styling, or branding directly in Courier without needing to touch code. You can preview notifications using test data and safely troubleshoot issues in a dedicated test environment before going live.
Because you're still sending messages through email APIs or SMTP, you remain dependent on a third-party service for delivery. However, notification services mitigate this risk with:
This extra resilience — combined with flexibility and visibility — makes notification services an attractive option for most teams. Courier’s free plan includes 10,000 notifications per month, making it easy to try out.
Nodemailer is a Node.js module used for sending emails and is the most popular Node.js email package. You can use Nodemailer to create HTML or plain-text emails, add attachments, and send your emails through different transport methods, including built-in SMTP support. It requires Node.js 6.0 or newer.
Let’s walk through how to send email using Nodemailer. The first step is to create a Node.js application:
Here you’ve created a folder and initialized a package.json
file using the npm init
command. The -y
flag is there to skip the interactive back-and-forth questions by npm.
Next, install the Nodemailer module:
Nodemailer’s createTransport
function specifies which method you want to use for sending email. It takes the connection data and credentials as an argument. In this case, since SMTP is the preferred transport, you will need to define an SMTP host, port, and credential password for accessing a host SMTP server.
To get a host URL, you need an SMTP server. For development purposes, you can use Mailtrap, or a similar service, to serve as a fake SMTP server. A fake SMTP server lets you avoid cluttering your real account with multiple tests while still seeing how your test emails behave — do all the buttons work the way they’re supposed to, is the formatting still correct after sending, and so on.
Create a Mailtrap account if you don’t already have one. In the Integrations dropdown on the dashboard, select Nodemailer and copy the credentials displayed.
Create an email.js
file and add the following:
Substitute the host, user, and password with the Mailtrap credentials you copied from the dashboard above. Now you can send an email using the sendMail
method of Nodemailer’s createTransport
function.
Append the following to the email.js
:
Nodemailer also supports sending emails using HTML. All you need to do is add the html
attribute to your message object like so:
To test that it works, go to your terminal and run:
Go to your Mailtrap dashboard to see your email was received.
There are a variety of email-as-a-service platforms and APIs, such as SendGrid and Mailgun, among others. For this article, I’ll demonstrate sending emails from within a Node application using SendGrid, which allows you to send up to 100 emails per month for free.
To start sending emails with SendGrid, the first step is to sign up for the service. Then you’ll need to create a SendGrid API key for sending email.
To create an API key, go to Settings > API Keys on SendGrid’s dashboard, then click “Create API Key.” Give the key a name, select “Full Access,” then click “Create & View.” Copy your API key and keep it safe for later use.
Next, install the SendGrid JavaScript client with npm:
Create a file in your project directory named sendgrid.js
:
In the sendgrid.js
file, add the following lines of code:
Replace the variable SENDGRID_API_KEY
with the SendGrid API key you created previously and make sure the email address in the From field has been verified by SendGrid. You can do this by creating a sender identity. This verifies that the email address actually belongs to you. Also, replace the email address in the To field from test@example.com
to your test recipient.
To test that it works, run:
To see if your email was delivered, check the SendGrid dashboard, and on the sidebar, select “Activity.” There, you should see the email you just sent. SendGrid will show you whether it was delivered or not and whether it has been opened.
Courier is a multichannel notifications platform that enables you to reach your users on any channel using one uniform API. With Courier, you can bring your own email service provider, including SMTP or Gmail, or any of the popular email APIs like SendGrid, Amazon SES, and Postmark.
To start using Courier, create an account. You can send up to 10,000 notifications per month for free. During the onboarding flow, you’ll be asked to give Courier permission to send email on your behalf from your Gmail account. You can skip this step if you’re planning on using a different ESP, but we recommend setting it up as the fastest way to test out sending from Courier.
To use Courier to send transactional emails, head to the Courier dashboard and select Designer on the lefthand menu. Then, click the “Create Notification” button.
Select Gmail in the provider selection modal and hit “Continue”.
From there, you’ll want to add the content for your email notification. You can use the toolbar to drag and drop blocks for text, images, buttons, and more. You can even add Markdown or add code blocks to further customize your email.
Next, send the email notification from within Node.js using the Courier npm package@trycourier/courier
. To install it, run:
Create a file in your app directory named courier.js
:
Courier will automatically generate a code snippet for your notification, which you can copy-paste from the Send tab. Add the following lines of code to the file:
The Courier package is imported into the file, and the Courier client is instantiated. The client takes an authentication token, which you can get from the Courier notification settings created earlier. Click the gear icon from within your notification and copy the masked auth token.
The Courier client has a send method which takes an event ID, which is either the notification ID or custom event that you’ve mapped to your notification. The recipient Id should be a unique string you can use to identify the recipient and look them up in data logs. Note that email
refers to the email address of the recipient.
To check the status of your email, head to the Data tab in your Courier dashboard. Courier will tell you if your email has been delivered, opened, and/or clicked. Courier will also tell you if there are any errors and when in the delivery pipeline they occurred.
Email is still foundational for transactional communication — but it’s no longer the only channel users rely on. From SMS and push notifications to Slack and in-app inboxes, modern applications need to reach users where they are.
If you're using Node.js, you have a few ways to implement email delivery:
The world is shifting toward multichannel communication. Users expect personalized, timely updates across email, mobile, and chat — and managing this complexity manually is no longer sustainable. That’s why we recommend Courier: a modern platform built for the realities of today’s apps. It lets you bring your own email provider (SMTP or API), design notifications visually or with code, and seamlessly expand to new channels — all from a single API.
🚀 Get started free — Sign up for Courier and start building multichannel notifications in minutes.
Courier is a notification service that centralizes all of your templates and messaging channels in one place which increases visibility and reduces engineering time.
Sign-up
Why ByteDance Built Lynx? Because React Native Left a Gap
ByteDance didn’t adopt React Native or Flutter. Instead, they built their own mobile framework: Lynx. With native rendering, support for multiple JavaScript frameworks, and a focus on performance, Lynx reflects a broader shift in how modern teams approach cross-platform development. In this post, we look at why it was built, what problems it solves, and whether it’s a sign of what’s coming next.
Mike Miller
April 01, 2025
Cross-Platform Development in 2025: Lynx vs. React Native vs. Flutter
Lynx, React Native, and Flutter each offer a unique approach to cross-platform development in 2025. Lynx brings a web-native workflow with full CSS support, React Native thrives on its vast ecosystem and React compatibility, while Flutter delivers consistent UIs with high-performance rendering. This breakdown explores their strengths, technical differences, and which framework suits your next project.
Mike Miller
March 10, 2025
Free Tools
Comparison Guides
Send up to 10,000 notifications every month, for free.
Get started for free
Send up to 10,000 notifications every month, for free.
Get started for free
© 2025 Courier. All rights reserved.
1mkdir email-nodeapp && cd email-nodeapp2npm init -y
1npm install nodemailer
1const nodemailer = require('nodemailer');2let transporter = nodemailer.createTransport({3host: 'smtp.mailtrap.io',4port: 2525,5auth: {6user: "<user>",7pass: "<pass>"8}9})
1message = {2from: "from-example@email.com",3to: "to-example@email.com",4subject: "Subject",5text: "Hello SMTP Email"6}7transporter.sendMail(message, **function**(err, info) {8if (err) {9console.log(err)10} else {11console.log(info);12}
1message = {2from: "from@email.com",3to: "to@email.com",4subject: "Subject",5html: "<h1>Hello SMTP Email</h1>"6}
1node email.js
1npm install --save @sendgrid/mail
1touch sendgrid.js
1const sendgrid = require('@sendgrid/mail');23const SENDGRID_API_KEY = "<SENDGRID_API_KEY>"45sendgrid.setApiKey(SENDGRID_API_KEY)67const msg = {8to: 'test@example.com',9// Change to your recipient10from: 'test@example.com',11// Change to your verified sender12subject: 'Sending with SendGrid Is Fun',13text: 'and easy to do anywhere, even with Node.js',14html: '<strong>and easy to do anywhere, even with Node.js</strong>',15}16sendgrid17.send(msg)18.then((resp) => {19console.log('Email sent\n', resp)20})21.catch((error) => {22console.error(error)23})
1node sendgrid.js
1npm install @trycourier/courier
1touch courier.js
1const { CourierClient } = require("@trycourier/courier");23const courier = CourierClient({ authorizationToken: "<AUTH_TOKEN>" });4courier.send({5eventId: "<EVENT ID>", *// your Notification ID6recipientId: "<RECIPIENT_ID", *// usually your system's User ID7profile: {8email: "<EMAIL_ADDRESS>"9},10data: {} *// optional variables for merging into templates }).then((resp) => {11console.log('Email sent', resp)12})13.catch((error) => {14console.error(error)15});