nestjs-mailer-core
v1.0.5
Published
๐ Powerful NestJS email module with template support (EJS, Handlebars, Pug), multiple transports, preview mode, and async configuration. Perfect alternative to @nestjs-modules/mailer
Downloads
497
Maintainers
Keywords
Readme
nestjs-mailer-core
๐ Powerful NestJS email module with template support, multiple transports, and async configuration
Features โข Installation โข Quick Start โข Documentation โข Examples
A comprehensive, production-ready NestJS module for sending emails using nodemailer. Supports EJS, Handlebars, and Pug templates, multiple transport configurations, preview mode, and async configuration. Perfect alternative to @nestjs-modules/mailer with enhanced features and better TypeScript support.
โจ Features
- ๐จ Template Support - Built-in adapters for EJS, Handlebars, and Pug with template caching
- ๐ง Multiple Transports - Configure and use multiple email transports (SMTP, Gmail, SES, etc.)
- โก Async Configuration - Full support for async module configuration with ConfigService
- ๐ Preview Mode - Test emails without sending, with file saving and auto-open options
- ๐ Type Safe - Complete TypeScript support with full type definitions
- ๐ Production Ready - Battle-tested, well-documented, and actively maintained
- ๐ง Flexible - Support for custom template adapters and all nodemailer transport types
- ๐ฆ Lightweight - Minimal dependencies, template engines are optional
- โ Verified Connections - Optional automatic transporter verification on startup
- ๐ฏ Easy to Use - Simple API, comprehensive documentation, and examples
๐ฆ Installation
npm install nestjs-mailer-core nodemailer
npm install --save-dev @types/nodemailerNote:
nodemaileris a peer dependency and must be installed separately.
npm install nestjs-mailer-core nodemailer
npm install --save-dev @types/nodemailerTemplate Engine Support (Optional)
Install the template engine you want to use:
# For EJS templates
npm install ejs
# For Handlebars templates
npm install handlebars
# For Pug templates
npm install pug๐ Quick Start
Get started in minutes with a simple email setup:
1. Import the module
import { Module } from '@nestjs/common';
import { MailerModule } from 'nestjs-mailer-core';
@Module({
imports: [
MailerModule.forRoot({
transport: {
host: 'smtp.example.com',
port: 587,
secure: false,
auth: {
user: '[email protected]',
pass: 'your-password',
},
},
defaults: {
from: '"No Reply" <[email protected]>',
},
}),
],
})
export class AppModule {}2. Use the service
import { Injectable } from '@nestjs/common';
import { MailerService } from 'nestjs-mailer-core';
@Injectable()
export class AppService {
constructor(private readonly mailerService: MailerService) {}
async sendWelcomeEmail(userEmail: string) {
await this.mailerService.sendMail({
to: userEmail,
subject: 'Welcome!',
html: '<h1>Welcome to our platform!</h1>',
});
}
}โ๏ธ Configuration Options
The module supports both synchronous and asynchronous configuration patterns:
Synchronous Configuration
MailerModule.forRoot({
transport: {
host: 'smtp.gmail.com',
port: 587,
secure: false,
auth: {
user: '[email protected]',
pass: 'your-app-password',
},
},
defaults: {
from: '"Support Team" <[email protected]>',
},
preview: false, // Set to true to preview emails without sending
})Asynchronous Configuration
MailerModule.forRootAsync({
useFactory: async (configService: ConfigService) => ({
transport: {
host: configService.get('SMTP_HOST'),
port: configService.get('SMTP_PORT'),
secure: false,
auth: {
user: configService.get('SMTP_USER'),
pass: configService.get('SMTP_PASS'),
},
},
defaults: {
from: configService.get('SMTP_FROM'),
},
}),
inject: [ConfigService],
})Using a Configuration Class
@Injectable()
export class MailerConfigService implements MailerOptionsFactory {
createMailerOptions(): MailerOptions {
return {
transport: {
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT),
secure: false,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
},
defaults: {
from: process.env.SMTP_FROM,
},
};
}
}
// In your module
MailerModule.forRootAsync({
useClass: MailerConfigService,
})๐ฎ Transport Options
Supports all transport types available in nodemailer:
You can use any transport option supported by nodemailer:
SMTP
transport: {
host: 'smtp.example.com',
port: 587,
secure: false,
auth: {
user: 'username',
pass: 'password',
},
}Gmail
transport: {
service: 'gmail',
auth: {
user: '[email protected]',
pass: 'your-app-password',
},
}Connection String
transport: 'smtps://user:[email protected]'Multiple Transports
You can configure multiple transports and use them by name:
MailerModule.forRoot({
transports: {
smtp: {
host: 'smtp.example.com',
port: 587,
secure: false,
auth: {
user: '[email protected]',
pass: 'password',
},
},
gmail: {
service: 'gmail',
auth: {
user: '[email protected]',
pass: 'your-app-password',
},
},
ses: {
SES: {
region: 'us-east-1',
// AWS credentials from environment or IAM role
},
},
},
defaults: {
from: '"No Reply" <[email protected]>',
},
})
// Use specific transport
await mailerService.sendMailWithTransport(
{
to: '[email protected]',
subject: 'Hello',
html: '<h1>Hello</h1>',
},
'gmail', // Use gmail transport
)Supported Transport Types
- SMTP - Standard SMTP transport
- SMTP Pool - SMTP connection pool
- Sendmail - Sendmail transport
- Stream - Stream transport
- JSON - JSON transport (for testing)
- SES - Amazon SES transport
- Connection String - URL-based configuration
๐ API Reference
Complete API documentation for MailerService:
MailerService
sendMail(options: SendMailOptions): Promise<SentMessageInfo>
Send an email. Accepts all options from nodemailer's sendMail method.
await mailerService.sendMail({
to: '[email protected]',
subject: 'Hello',
text: 'Plain text version',
html: '<h1>HTML version</h1>',
attachments: [
{
filename: 'document.pdf',
path: '/path/to/document.pdf',
},
],
});verifyConnection(): Promise<boolean>
Verify the transporter connection.
const isValid = await mailerService.verifyConnection();getTransporter(): Transporter
Get the default nodemailer transporter for advanced usage.
const transporter = mailerService.getTransporter();getTransport(transportName: string): Transporter | undefined
Get a specific transporter by name.
const gmailTransport = mailerService.getTransport('gmail');getAllTransports(): Map<string, Transporter>
Get all configured transporters.
const allTransports = mailerService.getAllTransports();sendMailWithTransport(options: SendMailOptions, transportName?: string): Promise<SentMessageInfo>
Send an email using a specific transport.
await mailerService.sendMailWithTransport(
{
to: '[email protected]',
subject: 'Hello',
html: '<h1>Hello</h1>',
},
'gmail', // Use gmail transport
)verifyConnection(transportName?: string): Promise<boolean>
Verify a specific transporter connection.
// Verify default transporter
const isValid = await mailerService.verifyConnection();
// Verify specific transport
const isGmailValid = await mailerService.verifyConnection('gmail');๐จ Template Support
Create beautiful, dynamic emails with template engines. Full support for EJS, Handlebars, and Pug:
The package supports template engines (EJS, Handlebars, Pug) for rendering email templates. Configure templates in your module:
Configuration with Templates
import { Module } from '@nestjs/common';
import { MailerModule } from 'nestjs-mailer-core';
import { join } from 'path';
@Module({
imports: [
MailerModule.forRoot({
transport: {
host: 'smtp.example.com',
port: 587,
secure: false,
auth: {
user: '[email protected]',
pass: 'your-password',
},
},
defaults: {
from: '"No Reply" <[email protected]>',
},
template: {
dir: join(__dirname, 'templates'), // Path to your template directory
engine: 'ejs', // or 'hbs', 'handlebars', 'pug', 'jade'
options: {
strict: false, // Template engine specific options
},
},
}),
],
})
export class AppModule {}Creating Templates
Create template files in your templates directory. For example, with EJS:
templates/welcome.ejs
<!DOCTYPE html>
<html>
<head>
<title>Welcome</title>
</head>
<body>
<h1>Welcome, <%= name %>!</h1>
<p>Thank you for joining us on <%= date %>.</p>
<p>Your account email is: <%= email %></p>
</body>
</html>templates/welcome.text.ejs (optional text version)
Welcome, <%= name %>!
Thank you for joining us on <%= date %>.
Your account email is: <%= email %>Sending Emails with Templates
Use the sendMailWithTemplate method to send emails using template files:
import { Injectable } from '@nestjs/common';
import { MailerService } from 'nestjs-mailer-core';
@Injectable()
export class UserService {
constructor(private readonly mailerService: MailerService) {}
async sendWelcomeEmail(userEmail: string, userName: string) {
await this.mailerService.sendMailWithTemplate({
to: userEmail,
subject: 'Welcome to our platform!',
template: 'welcome', // Template name (without extension)
context: {
name: userName,
email: userEmail,
date: new Date().toLocaleDateString(),
},
text: true, // Auto-generate text from HTML, or use 'welcome.text' template
});
}
}Template Engine Examples
EJS Templates
// templates/order-confirmation.ejs
<h1>Order Confirmation</h1>
<p>Order #<%= orderId %></p>
<ul>
<% items.forEach(item => { %>
<li><%= item.name %> - $<%= item.price %></li>
<% }); %>
</ul>
<p>Total: $<%= total %></p>
// Usage
await mailerService.sendMailWithTemplate({
to: userEmail,
subject: 'Order Confirmation',
template: 'order-confirmation',
context: {
orderId: '12345',
items: [
{ name: 'Product 1', price: 29.99 },
{ name: 'Product 2', price: 49.99 },
],
total: 79.98,
},
});Handlebars Templates
// templates/password-reset.hbs
<h2>Password Reset Request</h2>
<p>Hello {{name}},</p>
<p>Click the link below to reset your password:</p>
<a href="{{resetLink}}">Reset Password</a>
<p>This link expires in {{expiryHours}} hours.</p>
// Usage
await mailerService.sendMailWithTemplate({
to: userEmail,
subject: 'Password Reset',
template: 'password-reset',
context: {
name: 'John Doe',
resetLink: 'https://example.com/reset?token=abc123',
expiryHours: 1,
},
});Pug Templates
// templates/invoice.pug
h1 Invoice ##{invoiceNumber}
p Date: #{date}
table
thead
tr
th Item
th Quantity
th Price
tbody
each item in items
tr
td= item.name
td= item.quantity
td= item.price
// Usage
await mailerService.sendMailWithTemplate({
to: userEmail,
subject: 'Your Invoice',
template: 'invoice',
context: {
invoiceNumber: 'INV-001',
date: new Date().toLocaleDateString(),
items: [
{ name: 'Service A', quantity: 2, price: 100 },
{ name: 'Service B', quantity: 1, price: 50 },
],
},
});Template Options
The sendMailWithTemplate method accepts:
template: Template filename (without extension)context: Object with variables to pass to the templatetext:true- Auto-generate text from HTMLstring- Use custom textfalse- No text version- If not provided, will try to find
{template}.text.{ext}file
All other SendMailOptions are also supported (to, subject, cc, bcc, attachments, etc.)
Built-in Template Adapters
The package includes built-in adapters for EJS, Handlebars, and Pug. These adapters provide better performance through template caching:
import { MailerModule } from 'nestjs-mailer-core';
import { EjsAdapter } from 'nestjs-mailer-core';
import { HandlebarsAdapter } from 'nestjs-mailer-core';
import { PugAdapter } from 'nestjs-mailer-core';
import { join } from 'path';
// Using EJS Adapter
MailerModule.forRoot({
transport: { /* ... */ },
template: {
adapter: new EjsAdapter({
dir: join(__dirname, 'templates'),
options: {
strict: false,
},
}),
},
})
// Using Handlebars Adapter
MailerModule.forRoot({
transport: { /* ... */ },
template: {
adapter: new HandlebarsAdapter({
dir: join(__dirname, 'templates'),
options: {
helpers: {
// Custom Handlebars helpers
uppercase: (str: string) => str.toUpperCase(),
},
partials: {
// Custom Handlebars partials
header: join(__dirname, 'templates', 'partials', 'header.hbs'),
},
},
}),
},
})
// Using Pug Adapter
MailerModule.forRoot({
transport: { /* ... */ },
template: {
adapter: new PugAdapter({
dir: join(__dirname, 'templates'),
options: {
pretty: true,
},
}),
},
})Custom Template Adapters
You can also create your own template adapter:
import { TemplateAdapter } from 'nestjs-mailer-core';
class CustomTemplateAdapter implements TemplateAdapter {
compile(mail: any, callback: (err?: Error, body?: string) => void, mailerOptions: any): void {
// Your custom template compilation logic
const html = this.renderTemplate(mail.template, mail.data || mail.context);
callback(null, html);
}
private renderTemplate(template: string, data: any): string {
// Your template rendering logic
return '<html>...</html>';
}
}
MailerModule.forRoot({
transport: { /* ... */ },
template: {
adapter: new CustomTemplateAdapter(),
options: {
// Custom adapter options
},
},
})Note: When using adapters, the mail object passed to compile contains:
template: The template namedataorcontext: The template context/variables
Verify Transporters on Startup
You can automatically verify all transporters when the module initializes:
MailerModule.forRoot({
transport: { /* ... */ },
verifyTransporters: true, // Verify all transporters on startup
})This will verify the default transport and all named transports, logging success or failure for each.
Preview Mode
Enable preview mode to see email content without actually sending. Preview mode supports saving emails to files and optionally opening them:
// Simple preview (logs to console)
MailerModule.forRoot({
transport: {
// ... transport config
},
preview: true, // Emails will be logged instead of sent
})
// Advanced preview with file saving
MailerModule.forRoot({
transport: {
// ... transport config
},
preview: {
dir: './preview-emails', // Directory to save preview emails
open: true, // Automatically open preview files
},
})
// Preview with custom app
MailerModule.forRoot({
transport: {
// ... transport config
},
preview: {
dir: './preview-emails',
open: {
wait: false, // Don't wait for app to close
app: 'code', // Open with VS Code (or ['code', '--wait'] for multiple apps)
},
},
})Preview emails are saved as JSON files containing the full email data, making it easy to debug and test email templates.
๐ Why Choose nestjs-mailer-core?
| Feature | nestjs-mailer-core | @nestjs-modules/mailer | |---------|-------------------|------------------------| | Template Adapters | โ Built-in (EJS, HBS, Pug) | โ Built-in | | Template Caching | โ Yes | โ No | | Multiple Transports | โ Yes | โ Yes | | Preview Mode | โ Advanced (file saving) | โ Basic | | TypeScript Support | โ Full | โ Full | | Async Configuration | โ Yes | โ Yes | | Error Messages | โ Detailed & helpful | โ ๏ธ Basic | | Bundle Size | โ Smaller | โ ๏ธ Larger | | Active Maintenance | โ Yes | โ Yes | | Custom Adapters | โ Easy to implement | โ Yes |
๐ผ Use Cases
Perfect for:
- Transactional Emails - Welcome emails, password resets, order confirmations
- Marketing Campaigns - Newsletter, promotional emails, announcements
- Notifications - System alerts, user notifications, reminders
- Multi-tenant Applications - Different email providers per tenant
- Development & Testing - Preview mode for testing without sending emails
- Enterprise Applications - Multiple transport configurations, template management
๐ Performance
- Template Caching - Templates are compiled once and cached for better performance
- Connection Pooling - Support for SMTP connection pooling
- Lazy Loading - Template engines are loaded only when needed
- Minimal Dependencies - Lightweight package with optional template engines
๐ Search Keywords
This package is optimized for searches like:
- nestjs mailer
- nestjs email
- nestjs send email
- nestjs email templates
- nestjs nodemailer
- nestjs smtp
- nestjs email module
- nestjs transactional email
- nestjs email service
- nestjs mail module
๐ Additional Resources
- Troubleshooting Guide - Common issues and solutions
- Migration Guide - Migrate from @nestjs-modules/mailer
- Contributing Guide - How to contribute
- Security Policy - Security reporting and best practices
- Changelog - Version history and changes
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
โญ Star History
If you find this package useful, please consider giving it a star on GitHub!
๐ Acknowledgments
- Built on top of nodemailer - the amazing email library for Node.js
- Inspired by
@nestjs-modules/mailerwith additional features and improvements - Thanks to all contributors and users of this package
Made with โค๏ธ for the NestJS community
Report Bug โข Request Feature โข Documentation
