Skip to main content

Command Palette

Search for a command to run...

How to Send Emails for Free Using Nodemailer and Gmail SMTP

Published
5 min read
How to Send Emails for Free Using Nodemailer and Gmail SMTP

Sending emails for marketing campaigns, OTP verification, or customer support can sometimes be expensive. If you're looking for a way to send emails without spending a dime, you're in the right place.

In this tutorial, we'll walk through exactly how to set up free email sending using Nodemailer as our SMTP client and Gmail as our mail provider. That said, the core concepts apply to any SMTP client or email provider of your choice.


Understanding the Basics: Key Email Terminology

Before we write a single line of code, let's get familiar with a few terms you'll encounter when working with email infrastructure.

What is SMTP?

SMTP stands for Simple Mail Transfer Protocol. Think of it as the shared language that mail clients and mail servers use to communicate. Just like two people need a common language to understand each other, a mail client and mail server need SMTP to exchange messages.

We won't go deep into the internals of the protocol, but there are a handful of key concepts worth understanding.


SMTP Host

The SMTP host is the email server responsible for sending, receiving, and relaying outgoing emails between the sender and recipient. For Gmail, this is smtp.gmail.com.


SMTP Port

The SMTP port is the specific entry point on a server where the SMTP protocol operates. Different ports serve different purposes:

Port Protocol Description
587 STARTTLS Upgrades a plain-text connection to an encrypted one over the same port. Recommended for most use cases.
465 SSL/TLS Sends email over a fully encrypted connection from the start.
25 None The original, unencrypted SMTP port.
2525 STARTTLS An unofficial backup port, useful when 587 is blocked.

SMTP User

Your SMTP username is simply your email address (e.g., you@gmail.com). It's used to authenticate your application with the mail server.


SMTP Password

Your SMTP password is used alongside your username for authentication. For Gmail, this won't be your regular account password. We'll cover exactly what to use in the setup section below.


Setting Up Gmail for SMTP Authentication

Gmail doesn't allow you to authenticate with your regular account password when sending emails programmatically. Instead, you'll need to generate an App Password, which is a separate credential specifically for your application.

Step 1: Enable Two-Factor Authentication

Before you can create an App Password, 2FA must be active on your Google account.

  1. Go to your Google Account Security Settings

  2. Under "How you sign in to Google", enable 2-Step Verification

Step 2: Generate an App Password

  1. Visit Google App Passwords

  2. Enter your preferred app name

  3. Click Create and copy the password. You'll only see it once.

⚠️ Keep this password safe. Store it in your .env file and never commit it to version control.


Installing Nodemailer

Install Nodemailer via npm:

npm install nodemailer

Configuring Environment Variables

Create a .env file in your project root and add the following:

SMTP_HOST=smtp.gmail.com
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password

Note on ports: Use port 465 with SMTP_SECURE=true for SSL/TLS. Use port 587 with SMTP_SECURE=false for STARTTLS.


Creating the Nodemailer Transporter

The transporter is the core object in Nodemailer. It manages the connection to your email provider and handles sending messages.

import nodemailer from "nodemailer";

const transporter = nodemailer.createTransport({
  host: process.env.SMTP_HOST,
  port: Number(process.env.SMTP_PORT),
  secure: process.env.SMTP_SECURE === "true", // true for port 465, false for 587
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS,
  },
});

Sending an Email

With your transporter configured, sending an email is straightforward:

await transporter.sendMail({
  from: `"Your Name" <${process.env.SMTP_USER}>`,
  to: "recipient@example.com",
  subject: "Hello from Nodemailer!",
  text: "This is a plain text email.",
  html: "<p>This is an <strong>HTML</strong> email.</p>",
});

That's it. You're now sending emails for free using Gmail's SMTP server.


Putting It All Together

Here's a complete, reusable sendEmail utility function:

import nodemailer from "nodemailer";

const transporter = nodemailer.createTransport({
  host: process.env.SMTP_HOST,
  port: Number(process.env.SMTP_PORT),
  secure: process.env.SMTP_SECURE === "true",
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS,
  },
});

export async function sendEmail({ to, subject, text, html }) {
  return await transporter.sendMail({
    from: `"My App" <${process.env.SMTP_USER}>`,
    to,
    subject,
    text,
    html,
  });
}

Conclusion

In this guide, we covered:

  • The core SMTP concepts you need to know (host, port, credentials)

  • How to set up Gmail with an App Password for secure programmatic access

  • How to configure Nodemailer and send your first email

Gmail's free SMTP tier is a great starting point for low-to-medium volume sending. As your application scales, you may want to explore dedicated transactional email services like Resend, Mailgun, or SendGrid. For getting started without spending anything, though, this setup is hard to beat.

Happy sending!