Skip to main content
BlogWeb Dev

Resend vs Nodemailer: Transactional Email in 2025

A practical comparison of Resend and Nodemailer for transactional email — deliverability, developer experience, pricing, and when to use each.

Matthews Wong

Software Engineer

June 20258 min read
Web Dev

Nodemailer has 5.2 million weekly npm downloads and has been the standard for Node.js email since 2010. Resend has 500K weekly downloads but launched only in 2022 and is growing fast. The comparison isn't just about downloads — it's about what you're actually getting. Nodemailer is a transport layer; it connects to an SMTP server but the deliverability, IP reputation, and infrastructure are entirely your responsibility. Resend is a managed email API where deliverability is handled for you. Different tools for different problems.

DimensionNodemailerResend
What it isSMTP client library, bring your own serverManaged email API with hosted infrastructure
DeliverabilityYour responsibility: IP reputation, SPF, DKIM, DMARCHandled for you with warm IPs and automatic bounce handling
Developer experienceManual SMTP config and raw HTML templatesTypeScript SDK with React Email JSX templates
PricingFree with your own SMTP, or $0.10 per 1,000 emails via AWS SESFree tier of 3,000 emails a month, then $0.40 per 1,000 emails
Setup timeLonger: IAM roles, domain verification, SNS bounce topicsUnder an hour: install, API key, verify sending domain
Best use caseLocal testing, internal mail relays, high-volume SES sendingNew projects wanting managed deliverability and fast DX
Weekly npm downloads5.2 million500K, growing fast

Nodemailer: What It Is and Isn't

Nodemailer is an SMTP client library for Node.js. It connects to any SMTP server — Gmail, SendGrid, Mailgun, your own Postfix server — and sends emails through it. What it is NOT: it's not an email delivery service. Nodemailer doesn't have servers, doesn't manage IP reputation, doesn't handle bounces, and doesn't provide analytics. If you use Nodemailer with Gmail's SMTP, you're limited to 500 emails/day and are subject to Gmail's spam filters. If you use it with a fresh VPS-hosted Postfix server, your emails probably land in spam on day one.

Resend's Developer Experience

Resend's DX is genuinely excellent. The SDK is TypeScript-first with a clean API — one function call, returns a promise. Native React Email integration lets you write email templates as React components — JSX in your emails with real component composition and TypeScript safety. No template string interpolation, no HTML escaping issues. For a Next.js developer already thinking in React components, this workflow is natural. Setting up Resend from zero to first sent email takes under an hour.

Nodemailer (SMTP client)              Resend (managed API)
────────────────────────             ─────────────────────────
Your App                             Your App
    │                                    │
    ▼                                    ▼
Nodemailer createTransport()         resend.emails.send({
    │                                  from: 'hello@yourdomain.com',
    ▼                                  to: user.email,
SMTP Server (your choice):           react: <WelcomeEmail name={name} />,
├── Gmail: 500/day limit             })
├── AWS SES: $0.10/1k (cheap)
├── Your Postfix: IP reputation?     Resend handles:
└── SendGrid: requires setup         ├── IP reputation (managed)
                                     ├── SPF/DKIM/DMARC
npm downloads (2025):                ├── Bounce processing
Nodemailer: 5.2M/week               ├── Complaint handling
Resend: 500K/week (growing fast)    └── Analytics dashboard

Pricing comparison:
Resend:    $0.40/1k emails (free tier: 3k/month)
SES:       $0.10/1k emails (but: your infrastructure)
Postmark:  $1.50/1k emails (premium deliverability)
Gmail:     Free but 500/day cap → breaks in production

From integrating Resend in a production SaaS: use React Email for all transactional email templates, even simple ones. The component model pays dividends when you need to update branding — change one EmailLayout wrapper and every template updates. With Nodemailer + raw HTML templates, brand updates require touching every template file. The React Email preview server (email.dev) also makes iterating on templates dramatically faster.

Deliverability: The Real Reason to Pay

Email deliverability is complex — inbox placement depends on sending IP reputation, domain authentication (SPF, DKIM, DMARC), engagement metrics, and complaint rates. Resend (and other managed providers like Postmark and SendGrid) maintain warm sending IPs with established reputations, handle bounce and complaint processing automatically, and provide domain authentication setup guidance. When you use Resend, you inherit their IP reputation — for a new product, this is significantly better than a fresh IP.

# Install
npm install resend @react-email/components

# emails/WelcomeEmail.tsx (React Email component)
import { Html, Head, Body, Container, Text, Button } from "@react-email/components"

export function WelcomeEmail({ name, loginUrl }: { name: string; loginUrl: string }) {
  return (
    <Html>
      <Head />
      <Body style={{ fontFamily: "Inter, sans-serif", backgroundColor: "#f4f4f5" }}>
        <Container style={{ maxWidth: "560px", margin: "40px auto", padding: "40px", backgroundColor: "#fff", borderRadius: "12px" }}>
          <Text style={{ fontSize: "24px", fontWeight: "bold" }}>Welcome, {name}!</Text>
          <Text>Your account is ready. Click below to log in.</Text>
          <Button href={loginUrl} style={{ backgroundColor: "#3b82f6", color: "#fff", padding: "12px 24px", borderRadius: "8px" }}>
            Log In Now
          </Button>
        </Container>
      </Body>
    </Html>
  )
}

# app/api/send-welcome/route.ts
import { Resend } from "resend"
import { WelcomeEmail } from "@/emails/WelcomeEmail"

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

export async function POST(req: Request) {
  const { email, name } = await req.json()

  const { data, error } = await resend.emails.send({
    from: "Matthews Wong <hello@matthewswong.com>",
    to: email,
    subject: "Welcome to the platform",
    react: <WelcomeEmail name={name} loginUrl="https://app.example.com/login" />,
  })

  if (error) return Response.json({ error }, { status: 500 })
  return Response.json({ id: data?.id })
}

# Local development with Nodemailer + Ethereal (no real emails sent)
import nodemailer from "nodemailer"
const testAccount = await nodemailer.createTestAccount()
const transporter = nodemailer.createTransport({
  host: "smtp.ethereal.email",
  auth: { user: testAccount.user, pass: testAccount.pass },
})
const info = await transporter.sendMail({ ... })
console.log("Preview URL:", nodemailer.getTestMessageUrl(info))

Pricing Comparison

Resend's free tier covers 3,000 emails/month. Paid tiers start at roughly $0.40 per 1,000 emails. AWS SES via Nodemailer charges $0.10 per 1,000 emails — four times cheaper — but requires your own domain warm-up, bounce handling, SNS notification setup, and ongoing maintenance. For a product team focused on building features, the managed deliverability at $0.40/1,000 is usually worth it. For high-volume transactional email (millions/month), AWS SES becomes more attractive despite the infrastructure overhead.

Google limits Gmail SMTP to 500 emails/day for free accounts and 2,000/day for Google Workspace. More critically, Google aggressively rate-limits and blocks SMTP connections they deem suspicious. Your password-reset emails will start failing randomly as you scale. Gmail SMTP is acceptable for local development and testing. For production, use a dedicated transactional email API or at minimum a proper SMTP relay like Amazon SES, Mailgun, or SendGrid. The debugging time you'll spend on Gmail SMTP delivery failures exceeds the cost of any managed provider.

When Nodemailer Is the Right Choice

Nodemailer remains the right choice in specific scenarios: (1) You control an SMTP server (internal mail relay, Postfix on your infrastructure) and need to connect to it programmatically. (2) You're building an email testing workflow that catches outgoing email locally — combine Nodemailer with Ethereal.email or Mailhog for zero-cost local email testing. (3) You have a high-volume sending scenario and want AWS SES at $0.10/1,000 with direct SMTP access rather than an API client. In all other cases, a managed API (Resend, Postmark, Mailgun) provides better DX and deliverability.

What I Use and Why

I use Resend for all new projects. The React Email integration is the decisive factor — writing email templates as React components with TypeScript is genuinely better than managing HTML strings or template files. Resend's free tier is sufficient for early-stage projects (3,000 emails/month covers most side projects and early SaaS products), and the API is so simple that email integration takes an afternoon rather than a day. I reserve Nodemailer for local development testing with Ethereal.email — it's the best way to test email flows without hitting real SMTP limits.

Setting Up Resend in Next.js

Install: npm install resend @react-email/components. Set RESEND_API_KEY in your environment. Create a Route Handler or Server Action that calls resend.emails.send() with your React Email template as the react property. Verify your sending domain in the Resend dashboard (add the DKIM/SPF records they provide to your DNS). Done. The entire integration is ~20 lines of code plus your email template component. Compare that to a Nodemailer + AWS SES setup which requires IAM roles, SES domain verification, bounce/complaint SNS topics, and a custom transport configuration.

Sources & Further Reading

FAQ

Frequently Asked Questions

Short answers to what readers ask most about this topic.

What is the key difference between Resend and Nodemailer?

Nodemailer is an SMTP client library — it connects to any SMTP server but does not manage deliverability, IP reputation, or bounces. Resend is a managed email API that handles deliverability for you, including warm sending IPs, bounce processing, and domain authentication guidance. They solve different problems: Nodemailer is a transport layer, Resend is a full email delivery service.

Why does deliverability matter, and how does Resend help?

Inbox placement depends on sending IP reputation, domain authentication (SPF, DKIM, DMARC), engagement metrics, and complaint rates. When you self-host email via Nodemailer with a fresh VPS, your emails likely land in spam from day one. Resend maintains warm sending IPs with established reputations, so new products inherit that reputation instead of starting from scratch.

How does Resend's pricing compare to using Nodemailer with AWS SES?

Resend's free tier covers 3,000 emails per month, with paid tiers at roughly $0.40 per 1,000 emails. AWS SES via Nodemailer is four times cheaper at $0.10 per 1,000 emails, but requires your own domain warm-up, bounce handling, SNS notification setup, and ongoing maintenance. For product teams focused on building features, the managed deliverability at $0.40 per 1,000 is usually worth the premium.

Why is React Email a decisive factor for choosing Resend in a Next.js project?

Resend integrates natively with React Email, letting you write email templates as React components with JSX and TypeScript safety — eliminating HTML string management and escaping issues. Updating branding means changing one EmailLayout wrapper and every template updates automatically. The React Email preview server (email.dev) also makes iterating on templates significantly faster compared to managing raw HTML template files with Nodemailer.

When should you still use Nodemailer instead of a managed email API?

Nodemailer remains the right choice in three scenarios: when you control an SMTP server on your own infrastructure and need to connect programmatically; when building local email testing workflows using tools like Ethereal.email or Mailhog for zero-cost testing; and when sending at very high volume where AWS SES at $0.10 per 1,000 emails justifies the infrastructure overhead. In all other cases, a managed API provides better developer experience and deliverability.