xTaskjs 1.0 is live: role-based accounts, documentation, and a customizable interface.

Packages

@xtaskjs/mailer

Nodemailer-backed delivery, template rendering, named transports, and DI-friendly mail services.

npm install @xtaskjs/mailer nodemailer reflect-metadata Package path: packages/mailer

Overview

What this package owns in the runtime

Mailer integrates outbound email into the same xtask lifecycle used by controllers and persistence. It registers transports at startup, exposes injectable mail services and transporters, and supports inline, EJS, or Handlebars-backed templates.

What it provides

  • registerMailerTransport() supports SMTP, Mailtrap, JSON transport, stream transport, and custom transporter factories.
  • MailerService can send raw mail, render templates, and deliver template-driven messages.
  • registerMailerTemplate(), registerEjsTemplateRenderer(), and registerHandlebarsTemplateRenderer() support reusable email views.
  • InjectMailerService(), InjectMailerTransport(), and InjectMailerLifecycleManager() connect delivery into DI-managed services.

How it fits

  • Initialized automatically by @xtaskjs/core when the package is installed.
  • Used directly in the 08-email_express_app sample and in 07-security_express_app for protected profile notifications.
  • Works well beside security when mail actions should happen after authenticated requests.

Usage Chart

How strongly this package shapes the runtime

Bootstrap

4/5

Dependency Injection

4/5

Messaging

5/5

Rendering

4/5

Integrations

4/5

Package Flow

How this package moves through xtaskjs runtime phases

Before startup

Register transports, template renderers, and reusable templates while modules load so the mail catalog is ready before requests arrive.

During CreateApplication()

The mailer lifecycle publishes MailerService, named transporters, and optional startup verification into the DI container.

During app.close()

Transports marked for shutdown are closed automatically so SMTP or test transports do not leak resources.

API Surface

Representative exports from the upstream package

Transport registration

  • registerMailerTransport
  • createMailtrapTransportOptions
  • registerMailerTemplate
  • InjectMailerTransport

Service and templates

  • MailerService
  • InjectMailerService
  • registerEjsTemplateRenderer
  • registerHandlebarsTemplateRenderer

Lifecycle surface

  • InjectMailerLifecycleManager
  • initializeMailerIntegration
  • shutdownMailerIntegration

Usage

Typical adoption flow

1. Register one or more transports

Start with a default transport, then add named channels like notifications when internal and external emails should be separated.

2. Define templates and renderers

Choose inline templates or file-backed EJS or Handlebars renderers based on how much reuse or designer collaboration you need.

3. Inject MailerService into services

Send template-driven messages from DI-managed application services instead of scattering transport code across controllers.

Example

Reference snippet

Named transports plus template-driven delivery
import { Service } from "@xtaskjs/core";
import {
  InjectMailerService,
  MailerService,
  createMailtrapTransportOptions,
  registerMailerTemplate,
  registerMailerTransport,
} from "@xtaskjs/mailer";

const transport = process.env.MAIL_TRANSPORT_PROVIDER === "smtp"
  ? {
      host: process.env.MAIL_SMTP_HOST || "smtp.example.com",
      port: Number(process.env.MAIL_SMTP_PORT || 587),
      secure: process.env.MAIL_SMTP_SECURE === "true",
      auth: {
        user: process.env.MAIL_SMTP_USER || "user",
        pass: process.env.MAIL_SMTP_PASS || "pass",
      },
    }
  : createMailtrapTransportOptions({
      username: process.env.MAILTRAP_SMTP_USER || "user",
      password: process.env.MAILTRAP_SMTP_PASS || "pass",
      host: process.env.MAILTRAP_SMTP_HOST || "sandbox.smtp.mailtrap.io",
      port: Number(process.env.MAILTRAP_SMTP_PORT || 2525),
      secure: process.env.MAILTRAP_SMTP_SECURE === "true",
    });

registerMailerTransport({
  name: "default",
  defaults: { from: "hello@xtaskjs.dev" },
  transport,
  verifyOnStart: false,
});

registerMailerTemplate({
  name: "welcome-email",
  subject: "Welcome {{user.name}}",
  text: "Hello {{user.name}}",
  html: "<h1>Hello {{user.name}}</h1>",
});

@Service()
export class WelcomeMailerService {
  constructor(
    @InjectMailerService()
    private readonly mailer: MailerService
  ) {}

  async sendWelcome(to: string) {
    return this.mailer.sendTemplate("welcome-email", { user: { name: "Ada" } }, {
      message: { to },
    });
  }
}

Samples

Official samples to inspect next

Reference samples: 07-security_express_app and 08-email_express_app

Related

Packages commonly used with this one