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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@onetodone/mailer

v0.3.1

Published

Type-safe transactional emails for Node.js: built-in templates, branding, i18n and pluggable transports, fully customizable.

Readme

Mailer from OneToDone

npm version npm downloads CI types included license

@onetodone/mailer sends transactional emails from Node.js applications. Configure your branding once (logo, company name, colors, footer) and send any email with a single typed call. The package ships with ready-made templates for common account flows. Every email renders to table-based HTML that holds up across major email clients and comes with a plain-text version. Texts are localizable, built-in templates can be restyled, reworded or replaced, and your own templates get the same typed API.

Three emails sent with @onetodone/mailer: email verification, a one-time code and a new sign-in notice

Screenshots of every email are in Built-in templates. The live preview shows every email in every built-in language.

Why @onetodone/mailer

  • The emails, not just the tools to build them. Libraries such as React Email and MJML help you write email markup. This package ships the account emails themselves, already written, laid out and tested in major email clients.
  • Ready for users in other languages. Built-in texts come in many languages, with plural forms and dates formatted per locale.
  • Yours to change. Brand it from config, reword any text, or replace the layout and any template, all through the same typed API.
  • Fits your stack. Send over SMTP, through Resend or with your own transport, with recipes for Better Auth, Auth.js, Express, Fastify, Next.js, NestJS and BullMQ.

Features

  • Built-in templates for email verification, welcome emails, one-time codes, sign-in links, password reset, email address changes, security notices and account deletion.
  • One call to send an email. Template names autocomplete, and props are checked at compile time and validated at runtime.
  • Branding from configuration: logo, company name, colors, footer text and support address.
  • Built-in texts in many languages. Override any text, or add a locale that falls back to English key by key. Right-to-left languages, such as Arabic and Hebrew, render right to left.
  • Custom layouts and templates with the same typed API. Props are validated with any Standard Schema library, such as zod, valibot or arktype, and custom templates can bring their own texts per locale, plural forms included.
  • Table-based HTML with inline styles and an Outlook button fallback, plus a plain-text version of every email.
  • Attachments, such as invoices, and inline images through cid: for pictures without a public URL, such as QR codes.
  • SMTP delivery through nodemailer, delivery through the Resend API with no extra dependencies, memory and console transports for tests and development, or a transport of your own. Delivery errors tell retryable failures, such as rate limits, from rejected emails.
  • Safe defaults: interpolated values are escaped, links must be http: or https:, header injection is rejected, and hook events never contain the email body or attachment content.

Requirements

  • Node.js 22 or later. The main entry and the Resend transport also run on Bun, Deno and edge runtimes such as Cloudflare Workers, with no Node.js compatibility flags. SMTP delivery needs Node.js.
  • ESM or CommonJS. Type declarations are included and need TypeScript 5.4 or later.
  • Every built-in language ships in the main entry, so locale: '<code>' needs no setup. The entry is about 250 kB of JavaScript (47 kB gzipped); each language adds about 2 kB gzipped.
  • nodemailer 6 or later, only for SMTP delivery through @onetodone/mailer/smtp. Delivery through Resend with @onetodone/mailer/resend needs no extra package.

Install

npm install @onetodone/mailer

For SMTP delivery, also install nodemailer:

npm install nodemailer

Quick start

Create one mailer for your application:

// mailer.ts
import { createMailer } from '@onetodone/mailer'
import { smtpTransport } from '@onetodone/mailer/smtp'

export const mailer = createMailer({
  transport: smtpTransport({
    host: 'smtp.example.com',
    port: 465,
    secure: true,
    auth: { user: process.env.SMTP_USER!, pass: process.env.SMTP_PASS! },
  }),
  from: 'My App <[email protected]>',
  branding: {
    companyName: 'My App',
    appUrl: 'https://example.com',
    supportEmail: '[email protected]',
  },
})

Then send emails from anywhere in your code:

import { mailer } from './mailer'

await mailer.send('verifyEmail', {
  to: '[email protected]',
  props: {
    userName: 'Lizzie',
    verifyUrl: 'https://example.com/verify?token=abc123',
    expiresInMinutes: 1440,
  },
})

createMailer validates every setting when it is called. A typo or an invalid value throws a MailerError with code INVALID_CONFIG at startup, not on the first send.

Call await mailer.close() on shutdown to close the SMTP connections.

In CommonJS, use require:

const { createMailer } = require('@onetodone/mailer')
const { smtpTransport } = require('@onetodone/mailer/smtp')

Documentation

  • Built-in templates: when to send each template, and its props.
  • Sending emails: send options, address forms, attachments and inline images, and rendering without sending.
  • Configuration: every setting of createMailer.
  • Customization: branding and theme, layout, and your own templates with their texts.
  • Texts and locales: built-in languages, text overrides and your own locales.
  • Transports: SMTP, Resend, console, memory and your own transport.
  • Testing: tests with memoryTransport and render.
  • Recipes: Better Auth, Auth.js, Express, Fastify, Next.js, NestJS and background jobs.
  • Hooks: onSent and onError for logging and metrics.
  • Errors: MailerError codes and retries.
  • Security: escaping, link and header checks, and email client support.
  • Versioning and support: what counts as a breaking change, supported Node.js and TypeScript versions, and deprecations.

Versioning

The package follows semantic versioning. While the version is 0.x, breaking changes bump the minor version, so npm's default ^0.3.0 range stays within 0.3.x. Changes are listed in the changelog and in the GitHub releases. Versioning and support lists what counts as a breaking change and which Node.js and TypeScript versions are supported.

Contributing

Bug reports, fixes, new languages and translation fixes are welcome. See CONTRIBUTING.md, and report security problems privately as described in SECURITY.md.

License

MIT