Skip to main content

Best Email Libraries for Node.js in 2026

·PkgPulse Team

TL;DR

Nodemailer for SMTP/self-hosted; Resend for modern API-based sending; React Email for beautiful templates. Nodemailer (~5M weekly downloads) is the battle-tested SMTP library — works with any mail server. Resend (~300K downloads, fast-growing) is an API-first service with a clean SDK. React Email (~600K downloads) is a template system that works with any sender. The modern stack in 2026: React Email + Resend.

Key Takeaways

  • Nodemailer: ~5M weekly downloads — SMTP/self-hosted, works with Gmail, SendGrid, SES
  • Resend: ~300K downloads — API-first, React-native, $0 free tier (3K emails/mo)
  • React Email: ~600K downloads — cross-client templates using React components
  • nodemailer + SES — cheapest for high volume ($0.10/1K emails)
  • Resend + React Email — best DX for startups in 2026

Nodemailer (SMTP, Universal)

// Nodemailer — SMTP setup with various providers
import nodemailer from 'nodemailer';

// Gmail (for development/low volume)
const gmailTransport = nodemailer.createTransport({
  service: 'gmail',
  auth: {
    user: process.env.GMAIL_USER,
    pass: process.env.GMAIL_APP_PASSWORD, // App Password (not account password)
  },
});

// Amazon SES (for production, cheapest at scale)
const sesTransport = nodemailer.createTransport({
  host: 'email-smtp.us-east-1.amazonaws.com',
  port: 587,
  secure: false,
  auth: {
    user: process.env.SES_ACCESS_KEY_ID,
    pass: process.env.SES_SECRET_ACCESS_KEY,
  },
});

// SendGrid (API as SMTP)
const sendgridTransport = nodemailer.createTransport({
  host: 'smtp.sendgrid.net',
  port: 587,
  auth: {
    user: 'apikey',
    pass: process.env.SENDGRID_API_KEY,
  },
});
// Nodemailer — sending email
const transporter = nodemailer.createTransport({ /* config */ });

// Verify connection
await transporter.verify();

// Send with HTML
const info = await transporter.sendMail({
  from: '"Acme Team" <noreply@acme.com>',
  to: 'user@example.com',
  subject: 'Welcome to Acme!',
  text: 'Welcome to Acme! Your account is ready.',
  html: `
    <div style="font-family: sans-serif; max-width: 600px;">
      <h1>Welcome to Acme!</h1>
      <p>Your account is ready. <a href="https://acme.com/login">Log in now</a>.</p>
    </div>
  `,
  // Attachments
  attachments: [
    {
      filename: 'invoice.pdf',
      path: '/tmp/invoice.pdf',
      contentType: 'application/pdf',
    },
  ],
});

console.log('Message sent:', info.messageId);
// Nodemailer — with DKIM signing (required for good deliverability)
const transporter = nodemailer.createTransport({
  host: 'smtp.example.com',
  port: 587,
  auth: { user: '...', pass: '...' },
  dkim: {
    domainName: 'acme.com',
    keySelector: 'default',
    privateKey: process.env.DKIM_PRIVATE_KEY,
  },
});

Best for: Self-hosted email, full control over SMTP provider, existing mail server infrastructure.


Resend (Modern API)

// Resend — API-first, developer-friendly
import { Resend } from 'resend';

const resend = new Resend(process.env.RESEND_API_KEY);

// Simple send
const { data, error } = await resend.emails.send({
  from: 'Acme <noreply@acme.com>',
  to: ['user@example.com'],
  subject: 'Welcome to Acme!',
  html: '<h1>Welcome!</h1>',
});

if (error) {
  console.error('Failed to send:', error);
  return;
}

console.log('Sent:', data?.id);
// Resend + React Email — modern email templating
import { Resend } from 'resend';
import WelcomeEmail from '@/emails/WelcomeEmail'; // React Email component

const resend = new Resend(process.env.RESEND_API_KEY);

await resend.emails.send({
  from: 'Acme <noreply@acme.com>',
  to: user.email,
  subject: 'Welcome to Acme!',
  react: <WelcomeEmail name={user.name} />, // Render React → HTML automatically
});
// Resend — batch sending
await resend.batch.send([
  {
    from: 'noreply@acme.com',
    to: 'alice@example.com',
    subject: 'Your report is ready',
    html: '<p>Hi Alice...</p>',
  },
  {
    from: 'noreply@acme.com',
    to: 'bob@example.com',
    subject: 'Your report is ready',
    html: '<p>Hi Bob...</p>',
  },
]);

Best for: Startups and modern apps. 3K free emails/month, no SMTP config, built-in analytics.


React Email (Templates)

// React Email — cross-client email components
import {
  Html, Head, Body, Container, Section,
  Text, Button, Img, Link, Hr, Preview,
} from '@react-email/components';

interface WelcomeEmailProps {
  name: string;
  loginUrl: string;
}

export function WelcomeEmail({ name, loginUrl }: WelcomeEmailProps) {
  return (
    <Html>
      <Head />
      <Preview>Welcome to Acme — your account is ready</Preview>
      <Body style={{ backgroundColor: '#f6f9fc', fontFamily: 'sans-serif' }}>
        <Container style={{ maxWidth: '600px', margin: '0 auto', padding: '20px' }}>
          <Img
            src="https://acme.com/logo.png"
            width={120}
            height={40}
            alt="Acme"
          />
          <Section>
            <Text style={{ fontSize: '24px', fontWeight: 'bold' }}>
              Welcome, {name}!
            </Text>
            <Text style={{ color: '#666', lineHeight: '1.6' }}>
              Your account is ready. Click below to get started.
            </Text>
            <Button
              href={loginUrl}
              style={{
                backgroundColor: '#3B82F6',
                color: '#fff',
                padding: '12px 24px',
                borderRadius: '6px',
                textDecoration: 'none',
              }}
            >
              Log in to your account
            </Button>
          </Section>
          <Hr />
          <Text style={{ fontSize: '12px', color: '#999' }}>
            Acme Inc, 123 Main St, San Francisco, CA
            {' · '}
            <Link href="{{unsubscribe_url}}">Unsubscribe</Link>
          </Text>
        </Container>
      </Body>
    </Html>
  );
}
// React Email — preview server
// Run: npx react-email dev --dir emails --port 3001
// Opens a preview of all your email templates in browser

// renderAsync — render to HTML string
import { render } from '@react-email/render';
import WelcomeEmail from './WelcomeEmail';

const html = await render(<WelcomeEmail name="Alice" loginUrl="https://acme.com" />);
const text = await render(<WelcomeEmail name="Alice" loginUrl="https://acme.com" />, {
  plainText: true,
});

// Use with any sender:
await nodemailer.sendMail({ html, text, /* ... */ });
await resend.emails.send({ html, /* ... */ });
// React Email — works with all major senders
import { render } from '@react-email/render';

// Nodemailer
transporter.sendMail({ html: await render(<WelcomeEmail />) });

// Resend (native react prop)
resend.emails.send({ react: <WelcomeEmail /> });

// SendGrid
sgMail.send({ html: await render(<WelcomeEmail />) });

// AWS SES
ses.sendEmail({ Message: { Body: { Html: { Data: await render(<WelcomeEmail />) } } } });

Best for: Any project that needs beautiful, maintainable email templates. Framework-agnostic.


Pricing at Scale

ServiceFree Tier$10/mo$100/mo
Resend3K/mo50K/mo500K/mo
SendGrid100/day100K/mo1.5M/mo
Mailgun1K/mo (trial)50K/mo500K/mo
Postmark100/mo~50K/mo~600K/mo
AWS SES (self)~100K/mo~1M/mo
Self-hostedUnlimited*Unlimited*Unlimited*

*Self-hosted costs infrastructure + deliverability management. Nodemailer + VPS + Postfix is possible but requires SPF/DKIM/DMARC setup and IP reputation management.


When to Choose

ScenarioPick
New app, fast setupResend + React Email
Need beautiful templatesReact Email (pairs with any sender)
Full SMTP control, self-hostedNodemailer
High volume (millions), cost-sensitiveNodemailer + SES
Already on AWSaws-sdk SES (direct) or Nodemailer + SES
Need transactional + marketingSendGrid (both products)
Open source alternativenodemailer-sendmail (local MTA)

Compare email library package health on PkgPulse.

Comments

Stay Updated

Get the latest package insights, npm trends, and tooling tips delivered to your inbox.