Using the AWS SDK to Send Emails with Amazon SES in Node.js
Learn how to use the AWS SDK for JavaScript to send emails with Amazon SES including the API interface, templates, and configuration sets.
Using the AWS SDK to Send Emails with Amazon SES
The AWS SDK provides a more performant and feature-rich alternative to SMTP for sending emails with SES.
Step 1: Install the AWS SDK
npm install @aws-sdk/client-ses
Step 2: Configure the SES Client
// src/utils/sesClient.js const { SESClient } = require("@aws-sdk/client-ses"); const sesClient = new SESClient({ region: process.env.AWS_REGION || "us-east-1", credentials: { accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY } }); module.exports = sesClient;
Step 3: Send a Simple Email
const { SendEmailCommand } = require("@aws-sdk/client-ses"); const sesClient = require("./utils/sesClient"); const sendEmail = async (to, subject, html, text) => { const params = { Source: process.env.SES_FROM, Destination: { ToAddresses: [to] }, Message: { Subject: { Data: subject, Charset: "UTF-8" }, Body: { Html: { Data: html, Charset: "UTF-8" }, Text: { Data: text, Charset: "UTF-8" } } } }; try { const command = new SendEmailCommand(params); const result = await sesClient.send(command); console.log("Email sent:", result.MessageId); return result; } catch (err) { console.error("SES error:", err); throw err; } }; // Usage await sendEmail( "[email protected]", "Welcome to DevTinder", "<h1>Welcome!</h1>", "Welcome to DevTinder!" );
Step 4: Send to Multiple Recipients
const params = { Source: process.env.SES_FROM, Destination: { ToAddresses: ["[email protected]", "[email protected]"], CcAddresses: ["[email protected]"], BccAddresses: ["[email protected]"] }, Message: { Subject: { Data: "Newsletter", Charset: "UTF-8" }, Body: { Html: { Data: "<p>Newsletter content</p>", Charset: "UTF-8" } } } };
Step 5: Use SES Templates
SES templates are stored on AWS and reused across emails:
const { CreateTemplateCommand, SendTemplatedEmailCommand } = require("@aws-sdk/client-ses"); // Create a template (one-time) const createTemplate = async () => { const params = { Template: { TemplateName: "WelcomeEmail", SubjectPart: "Welcome to DevTinder, {{firstName}}!", HtmlPart: "<h1>Welcome, {{firstName}}!</h1><p>Your account is ready.</p>", TextPart: "Welcome, {{firstName}}! Your account is ready." } }; await sesClient.send(new CreateTemplateCommand(params)); }; // Send using template const sendTemplatedEmail = async (to, templateName, templateData) => { const params = { Source: process.env.SES_FROM, Destination: { ToAddresses: [to] }, Template: templateName, TemplateData: JSON.stringify(templateData) }; const result = await sesClient.send(new SendTemplatedEmailCommand(params)); return result; }; // Usage await sendTemplatedEmail("[email protected]", "WelcomeEmail", { firstName: "John" });
Step 6: Use Configuration Sets for Tracking
const params = { Source: process.env.SES_FROM, Destination: { ToAddresses: [to] }, Message: { ... }, ConfigurationSetName: "DevTinderConfigSet" };
Configuration sets enable:
- Open tracking (pixel image)
- Click tracking (link wrapping)
- Bounce and complaint notifications
- Event publishing to CloudWatch or SNS
Step 7: Handle Bounces and Complaints
const { GetIdentityVerificationAttributesCommand } = require("@aws-sdk/client-ses"); // Check if an email bounced const checkBounce = async (email) => { // Set up SNS notification for bounces // When a bounce occurs, SES sends a notification to SNS // Your app processes the SNS message and marks the email as bounced // Mark bounced emails in your database await User.findOneAndUpdate( { email }, { emailBounced: true, emailBouncedAt: new Date() } ); };
AWS SDK vs SMTP: Which to Use?
| Feature | AWS SDK | SMTP |
|---|---|---|
| Performance | Better (no SMTP overhead) | Good |
| Templates | Yes (SES templates) | Manual (Nodemailer) |
| Configuration sets | Yes | Limited |
| Error handling | Detailed AWS errors | Generic SMTP errors |
| Setup | AWS credentials | SMTP credentials |
| Library | @aws-sdk/client-ses | Nodemailer |
Use AWS SDK if: You're already using AWS, want templates, need configuration sets, or want better performance. Use SMTP if: You're using Nodemailer or migrating from another SMTP service.
The Takeaway
The AWS SDK provides a more feature-rich interface for SES than SMTP. Use SendEmailCommand for simple emails, CreateTemplateCommand and SendTemplatedEmailCommand for reusable templates, and ConfigurationSetName for tracking. The SDK is faster than SMTP and integrates better with AWS services like SNS for bounce handling.
Install @aws-sdk/client-ses, create an SESClient with AWS credentials, then use SendEmailCommand with Source, Destination (ToAddresses), and Message (Subject, Body with Html and Text). Call sesClient.send(command) to send.
Create a template with CreateTemplateCommand (TemplateName, SubjectPart, HtmlPart, TextPart with {{variables}}). Send with SendTemplatedEmailCommand, passing TemplateData as a JSON string with variable values. Templates are stored on AWS and reused across emails.
Configuration sets are groups of rules for email sending open tracking (pixel), click tracking (link wrapping), bounce/complaint notifications via SNS, and event publishing to CloudWatch. Add ConfigurationSetName to your send params to enable tracking.
Use the AWS SDK for better performance, SES templates, configuration sets, and detailed error handling. Use SMTP (with Nodemailer) if you're migrating from another service, prefer Nodemailer's API, or need to switch email providers easily.
Set up SNS notifications for bounces in SES configuration sets. When a bounce occurs, SES publishes to SNS, your app processes the SNS message, and you mark the email as bounced in your database. Never send to bounced addresses again to protect your sender reputation.
Ready to master Node.js completely?
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.
Master Node.js
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course.

