Email30-45 min
Nodemailer Email Implementation
This guide covers SMTP configuration, transporter setup, reusable email functions, HTML/text templates, password reset emails, error handling, and deliverability basics.
Node.jsNodemailerSMTP
Prerequisites
- SMTP credentials from a provider such as Resend, Postmark, SendGrid, Mailgun, or your own mail server.
- A verified sender domain or sender email.
- Server-side environment variables.
- A transactional use case such as welcome email, password reset, or invoice notification.
1
Install Nodemailer
Implementation snippet
npm install nodemailer
npm install -D @types/nodemailer2
Add SMTP environment variables
Implementation snippet
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=apikey
SMTP_PASS=replace-with-secret
MAIL_FROM="CodersArts <hello@example.com>"3
Create a mail transporter
Implementation snippet
import nodemailer from "nodemailer";
export const transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: Number(process.env.SMTP_PORT || 587),
secure: Number(process.env.SMTP_PORT) === 465,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
});
export async function verifyEmailConnection() {
await transporter.verify();
}4
Create a reusable send helper
- Accept `to`, `subject`, `html`, and optional text content.
- Always include a plain-text fallback.
- Centralize the from address.
- Log provider message IDs for debugging.
Implementation snippet
export async function sendEmail({ to, subject, html, text }) {
const result = await transporter.sendMail({
from: process.env.MAIL_FROM,
to,
subject,
html,
text: text || html.replace(/<[^>]+>/g, ""),
});
return { messageId: result.messageId };
}5
Send a transactional email
Implementation snippet
export async function sendWelcomeEmail(user: { email: string; name: string }) {
return sendEmail({
to: user.email,
subject: "Welcome to the app",
html: `<h1>Welcome, ${user.name}</h1><p>Your account is ready.</p>`,
text: `Welcome, ${user.name}. Your account is ready.`,
});
}6
Add retries for production
- For low-volume apps, catch errors and retry once after a short delay.
- For production workflows, enqueue emails in a job queue such as BullMQ, Cloud Tasks, or your database.
- Mark emails as sent only after the provider accepts the message.
- Store failure reason and retry count for support/debugging.
7
Deliverability checklist
Checklist
- Verify SPF, DKIM, and DMARC for your sending domain.
- Use transactional providers instead of personal Gmail SMTP in production.
- Avoid sending sensitive secrets directly in email.
- Use short-lived links for password reset and magic-login emails.
- Include a text version for every important transactional email.