Integration Guide

SMTP testing with Node.js

Set up Nodemailer with MailHog to capture and inspect every email your Node.js app sends — locally, in staging, and in CI.

Why test emails in Node.js with MailHog?

Node.js applications send emails for password resets, order confirmations, magic links, and notifications. Without a test SMTP server, you either send to real addresses (risky), use console logging (incomplete), or skip email testing entirely. MailHog captures every email with full MIME parsing so you can verify content, headers, and rendering without any risk.

Quickstart: Nodemailer + MailHog

Install Nodemailer and configure it to use MailHog's SMTP server:

npm install nodemailer
const nodemailer = require("nodemailer");

const transporter = nodemailer.createTransport({
  host: process.env.SMTP_HOST || "smtp.mailhog.site",
  port: parseInt(process.env.SMTP_PORT || "2525"),
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS,
  },
});

// Send a test email
await transporter.sendMail({
  from: "app@yourcompany.com",
  to: "user@example.com",
  subject: "Reset your password",
  html: "<h1>Password Reset</h1><p>Click the link below...</p>",
});

// Email is now visible in your MailHog dashboard ✅

Environment configuration

Add these to your .env file:

SMTP_HOST=smtp.mailhog.site
SMTP_PORT=2525
SMTP_USER=your-inbox-username
SMTP_PASS=your-inbox-password

Testing with Jest

Use MailHog's API to assert on captured emails in your test suite:

test("sends password reset email", async () => {
  // Trigger password reset in your app
  await request(app)
    .post("/api/forgot-password")
    .send({ email: "user@test.com" });

  // Check MailHog for the email
  const res = await fetch(
    `${MAILHOG_URL}/api/v1/inbox/${INBOX_ID}/messages`,
    { headers: { "X-API-Key": API_KEY } }
  );
  const { data } = await res.json();

  expect(data[0].subject).toBe("Reset your password");
  expect(data[0].to[0].address).toBe("user@test.com");
  expect(data[0].html).toContain("Reset Password");
});

Common pitfalls with Nodemailer

  • Forgetting to set secure: false when using port 2525 (not TLS by default)
  • Using tls.rejectUnauthorized: false in development but shipping it to production
  • Hardcoding SMTP credentials instead of using environment variables
  • Not testing multipart emails (HTML + plain text fallback)

Related guides

Start testing Node.js emails

Get SMTP credentials in 60 seconds. Free plan available.

Start free →