Skip to content

Comparison with @nestjs/mail ​

Two NestJS mail packages now exist: this one, @nestjs-modules/mailer (community-maintained, built on nodemailer), and the official @nestjs/mail (NestJS team, first released as 0.0.1, no third-party dependencies). This page compares @nestjs-modules/mailer v4 with @nestjs/mail 0.0.1 as honestly as we can, so you can pick the right one, or use both together. If something here is out of date, please open an issue.

At a glance ​

@nestjs-modules/mailer v4@nestjs/mail 0.0.1
FoundationnodemailerIts own SMTP client and MIME builder on Node.js built-ins
Runtime dependenciesnodemailer, css-inline, glob (+ the template engine you choose); the HTTP transports themselves add noneNone
Module formatCommonJS (loads ESM-only NestJS 12 via require(esm))ESM only
NestJS11 and 1211 and 12

Features ​

Feature@nestjs-modules/mailer v4@nestjs/mail 0.0.1
Template enginesHandlebars, Pug, EJS, MJML, Liquid, Nunjucks, with CSS inlining; custom resolvers (DB, S3)FileTemplateEngine (logic-less HTML: escaping, conditionals, loops, partials), or your own engine
html tag, plain text from HTMLYes (html, unsafeHtml(), textFromHtml)Yes
SMTP and nodemailer transportsAnything nodemailer supports: SMTP (pooled), SES SDK, sendmail, streams, community transportsIts own SMTP client
HTTP provider transportsBuilt-in, zero-dependency: Resend, Postmark, SendGrid, SES, Mailgun, BrevoBuilt-in: Resend, Postmark, SendGrid, SES
Dev and test transportsFileTransport, LogTransport, TestMailboxFileMailTransport, LogMailTransport, InMemoryMailTransport
Warning for a non-delivering transport in productionYesYes
Typed mail classesYes (Mailable), same shapeYes (Mailable)
Render without sendingYes (render())Yes (render())
Typed errors with permanent flagYes (MailerError and subclasses)Yes (MailError and subclasses)
Message validation before sendingYes (validate)Yes
Retries with backoffYes, on by default (3 attempts), transient/permanent classification, Retry-After, duplicate protection for ambiguous failuresYes, on by default (3 attempts), transient/permanent classification, Retry-After
Abort signal, idempotency keyYesYes
Graceful shutdown (drain())Yes (shutdownTimeout)Yes
Failover between transportsYes (failover)No
Multiple named transportsYes, also added at runtimeOne transport per module
Transactional outboxYes, through @nestjs/outbox (MailerOutboxModule)Yes, through @nestjs/outbox
Background queueBullMQ queue with scheduling, priorities and concurrency (needs Redis)No
Batch sendingYes (MailerBatchService, concurrency and rate limit)No
Staging interceptionYes (intercept)No
Suppression listsYes (suppress)No
One-click unsubscribe (RFC 8058)Yes (unsubscribe)No dedicated option (set the headers yourself)
Test mailbox with assertionsYes (MailerTestModule, TestMailbox)Yes (InMemoryMailTransport)
Preview UI in the browserYes (MailerPreviewModule), plus preview-email integrationNo
EventsBefore send, after send, error, retry, failover, suppressed, queue events; RxJS events$, @nestjs/event-emitter, diagnostics_channelSent and failed; events$ and diagnostics_channel
Health checkYes (MailerHealthIndicator for @nestjs/terminus)No health indicator (SmtpTransport has a verify() you can call)
i18nFolder per locale, region → language fallback, default-locale fallbackLocale suffix on template names (welcome.es.html)
DKIMYes (nodemailer dkim)Yes (SMTP transport)
nodemailer pluginsYesNo

Choosing ​

  • Choose @nestjs/mail for a new project when its built-in transports and template engine cover your needs and you value zero dependencies and an official package.
  • Choose @nestjs-modules/mailer when you need richer template engines, nodemailer transports or plugins, Mailgun or Brevo, failover, staging interception, suppression, a browser preview, batches or a Redis-backed queue, or when you already use it.
  • Combine them with the @nestjs-modules/mailer/nestjs-mail adapters: @nestjs/mail's API with nodemailer transports, this module's delivery features or its template engines.

Released under the MIT License.