npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

Iโ€™ve always been into building performant and accessible sites, but lately Iโ€™ve been taking it extremely seriously. So much so that Iโ€™ve been building a tool to help me optimize and monitor the sites that I build to make sure that Iโ€™m making an attempt to offer the best experience to those who visit them. If youโ€™re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, ๐Ÿ‘‹, Iโ€™m Ryan Hefnerย  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If youโ€™re interested in other things Iโ€™m working on, follow me on Twitter or check out the open source projects Iโ€™ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soonโ€“ish.

Open Software & Tools

This site wouldnโ€™t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you ๐Ÿ™

ยฉ 2025 โ€“ย Pkg Stats / Ryan Hefner

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

Readme

nestjs-mailer-core

npm version npm downloads npm license TypeScript NestJS

๐Ÿš€ 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/nodemailer

Note: nodemailer is a peer dependency and must be installed separately.

npm install nestjs-mailer-core nodemailer
npm install --save-dev @types/nodemailer

Template 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 template
  • text:
    • true - Auto-generate text from HTML
    • string - Use custom text
    • false - 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 name
  • data or context: 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

๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. 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/mailer with additional features and improvements
  • Thanks to all contributors and users of this package

Made with โค๏ธ for the NestJS community

Report Bug โ€ข Request Feature โ€ข Documentation