Fake SMTP Server
Fake SMTP Server is a utility designed for email testing within QA and development workflows. It provides a local, in-memory SMTP server that captures all incoming emails, preventing them from being sent to real recipients. The captured emails can then be inspected manually via a web interface or programmatically through a RESTful API. The package is currently at version 0.8.0. While a strict release cadence isn't published, it appears actively maintained through its GitHub repository. Key differentiators include its ease of installation and use as a standalone server, making it ideal for local development and Continuous Integration (CI) environments where actual email sending is undesirable or complex to mock.
Common errors
-
EADDRINUSE: address already in use :::1025
cause Another process is already listening on the default SMTP port (1025) or the HTTP port (1080). This could be a previous instance of `fake-smtp-server` or another application.fixStop the conflicting process or start `fake-smtp-server` on different ports using `fake-smtp-server --smtp-port 2525 --http-port 1081` (CLI) or by specifying `smtpPort` and `httpPort` options programmatically. -
Error: connect ECONNREFUSED 127.0.0.1:1025
cause Your email client or test code is trying to connect to the SMTP server, but the `fake-smtp-server` is either not running or not listening on the expected IP address and port.fixEnsure `fake-smtp-server` is running. Verify the SMTP host and port configured in your email client or test code match the server's settings (default: `localhost:1025`). -
No emails found when querying the API, even after sending.
cause Several potential causes: 1) Email was sent to the wrong SMTP port/host. 2) The `--max` limit was reached, and older emails were purged. 3) API filters (`from`, `to`, `since`, `until`) are too restrictive or incorrect. 4) The email was malformed and not processed.fix1) Double-check SMTP port/host settings. 2) Increase `--max` limit. 3) Remove API filters or simplify them to `GET /api/emails` to see all emails. 4) Check the email content and format being sent.
Warnings
- gotcha Custom email headers are not captured by default and will not appear in API responses. To enable header capture, you must start the server with the `--headers` CLI flag or by passing `headers: true` in the options object if using the programmatic API.
- gotcha The server has a default limit of 100 stored emails. If more emails are received, older ones will be purged. This can lead to unexpected missing emails in automated tests.
- gotcha By default, the server listens on standard development ports (SMTP: 1025, HTTP: 1080). These ports can often conflict with other local services or previous instances of `fake-smtp-server`, leading to 'EADDRINUSE' errors.
- gotcha When filtering emails via the API using `since` and `until` parameters, ensure the date formats match the ISO 8601 standard (e.g., `YYYY-MM-DDTHH:mm:ssZ`). Incorrect formats may lead to no results being returned.
Install
-
npm install fake-smtp-server -
yarn add fake-smtp-server -
pnpm add fake-smtp-server
Imports
- createServer
const FakeSmtpServer = require('fake-smtp-server');import { createServer } from 'fake-smtp-server'; - FakeSmtpServerOptions
import type { FakeSmtpServerOptions } from 'fake-smtp-server';
Quickstart
import { createServer } from 'fake-smtp-server';
import { createTransport } from 'nodemailer';
import fetch from 'node-fetch'; // For HTTP API interaction
async function runEmailTest() {
const smtpPort = 2525;
const httpPort = 1081;
console.log(`Starting Fake SMTP Server on SMTP port ${smtpPort}, HTTP port ${httpPort}...`);
const server = createServer({
smtpPort,
httpPort,
headers: true // Enable headers for richer email data
});
await server.start();
console.log('Fake SMTP Server started.');
// Configure Nodemailer to send to our fake SMTP server
const transporter = createTransport({
host: 'localhost',
port: smtpPort,
secure: false, // Use plain SMTP for testing
tls: {
rejectUnauthorized: false
}
});
const testEmail = {
from: 'sender@example.com',
to: 'recipient@example.com',
subject: 'Test Email from Fake SMTP Server',
text: 'This is a test email sent to the fake SMTP server.',
html: '<b>This is a test email</b> sent to the fake SMTP server.'
};
console.log('Sending test email...');
await transporter.sendMail(testEmail);
console.log('Test email sent.');
console.log('Fetching received emails from API...');
const response = await fetch(`http://localhost:${httpPort}/api/emails?to=${testEmail.to}`);
const emails = await response.json();
if (emails.length > 0) {
console.log(`Received ${emails.length} email(s):`);
console.log(JSON.stringify(emails[0], null, 2));
if (emails[0].subject !== testEmail.subject) {
console.error('ERROR: Email subject mismatch!');
}
} else {
console.error('ERROR: No emails received!');
}
console.log('Clearing all emails via DELETE API...');
await fetch(`http://localhost:${httpPort}/api/emails`, { method: 'DELETE' });
const afterDelete = await (await fetch(`http://localhost:${httpPort}/api/emails`)).json();
console.log(`Emails after clear: ${afterDelete.length}`);
console.log('Stopping Fake SMTP Server...');
await server.stop();
console.log('Fake SMTP Server stopped.');
}
runEmailTest().catch(console.error);