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

usesend-nodemailer

v0.1.3

Published

Transport for Nodemailer to send mails using the Usesend API.

Readme

Usesend Nodemailer

A Nodemailer transport package that enables sending emails through the Usesend API with enhanced error handling and validation.

Features

  • ✅ Full Nodemailer Transport interface support
  • ✅ Automatic email validation with detailed error messages
  • ✅ Display name support ("Name <[email protected]>")
  • ✅ Automatic text/HTML content handling
  • Comprehensive attachment support with automatic base64 encoding
    • String, Buffer, and Stream content
    • File paths (local filesystem)
    • URLs (HTTP/HTTPS)
    • Data URIs
    • Pre-encoded base64 content
    • Multiple attachments (up to 10 per email)
  • ✅ Custom API endpoint support
  • ✅ Enhanced error reporting with helpful hints
  • ✅ TypeScript support with full type definitions

Installation

npm

npm install usesend-nodemailer

pnpm

pnpm add usesend-nodemailer

bun

bun add usesend-nodemailer

Quick Start

import { UsesendTransport } from 'usesend-nodemailer';
import { createTransport } from 'nodemailer';

// Create transport
const mailer = createTransport(
  UsesendTransport.makeTransport({
    apiKey: 'your_usesend_api_key'
  })
);

// Send email
await mailer.sendMail({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Hello from Usesend!',
  html: '<h1>Welcome!</h1><p>This is a test email.</p>',
});

Configuration

Basic Configuration

const mailer = createTransport(
  UsesendTransport.makeTransport({
    apiKey: 'your_usesend_api_key'
  })
);

Custom API Endpoint

If you need to use a custom Usesend API endpoint (e.g., self-hosted instance):

const mailer = createTransport(
  UsesendTransport.makeTransport({
    apiKey: 'your_usesend_api_key',
    apiUrl: 'https://your-custom-endpoint.com'
  })
);

Environment Variables

You can also use environment variables:

USESEND_API_KEY=your_api_key
USESEND_URL=https://your-custom-endpoint.com  # Optional

Usage Examples

Basic Email

await mailer.sendMail({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Welcome!',
  html: '<h1>Welcome to our service!</h1>',
});

Email with Display Names

The transport supports display names in email addresses:

await mailer.sendMail({
  from: 'Your Company <[email protected]>',
  to: 'John Doe <[email protected]>',
  subject: 'Personalized Email',
  html: '<p>Hello John!</p>',
});

Email with Multiple Recipients

await mailer.sendMail({
  from: '[email protected]',
  to: ['[email protected]', '[email protected]'],
  cc: '[email protected]',
  bcc: ['[email protected]'],
  subject: 'Team Update',
  html: '<p>Important team announcement</p>',
});

Email with Plain Text and HTML

await mailer.sendMail({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Multi-format Email',
  text: 'This is the plain text version.',
  html: '<h1>This is the HTML version</h1>',
});

Note: If you only provide HTML, the transport automatically generates a plain text version by stripping HTML tags. If you only provide text, it's used for both formats.

Email with Attachments

The transport supports comprehensive attachment handling with automatic base64 encoding. You can attach files using various methods:

String Content

await mailer.sendMail({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Text File Attachment',
  html: '<p>Please find the text file attached.</p>',
  attachments: [
    {
      filename: 'hello.txt',
      content: 'Hello, world!',
    }
  ],
});

Buffer Content

await mailer.sendMail({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'PDF Document',
  html: '<p>Document attached.</p>',
  attachments: [
    {
      filename: 'document.pdf',
      content: Buffer.from(pdfData),
    }
  ],
});

File Path

await mailer.sendMail({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'File from Disk',
  html: '<p>File attached from filesystem.</p>',
  attachments: [
    {
      filename: 'report.pdf',
      path: '/path/to/report.pdf',
    }
  ],
});

URL (HTTP/HTTPS)

await mailer.sendMail({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'File from URL',
  html: '<p>Image attached from URL.</p>',
  attachments: [
    {
      filename: 'logo.png',
      path: 'https://example.com/logo.png',
    }
  ],
});

Data URI

await mailer.sendMail({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Data URI Attachment',
  html: '<p>Inline data attached.</p>',
  attachments: [
    {
      filename: 'inline.txt',
      path: 'data:text/plain;base64,SGVsbG8gV29ybGQh',
    }
  ],
});

Stream Content

import { createReadStream } from 'fs';

await mailer.sendMail({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Large File Stream',
  html: '<p>Large file attached via stream.</p>',
  attachments: [
    {
      filename: 'large-file.zip',
      content: createReadStream('/path/to/large-file.zip'),
    }
  ],
});

Pre-encoded Base64

await mailer.sendMail({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Base64 Encoded',
  html: '<p>Pre-encoded content.</p>',
  attachments: [
    {
      filename: 'encoded.pdf',
      content: 'JVBERi0xLjQK...', // base64 encoded content
      encoding: 'base64',
    }
  ],
});

Multiple Attachments

await mailer.sendMail({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Multiple Files',
  html: '<p>Multiple files attached.</p>',
  attachments: [
    {
      filename: 'document.pdf',
      path: '/path/to/document.pdf',
    },
    {
      filename: 'spreadsheet.xlsx',
      content: Buffer.from(xlsxData),
    },
    {
      filename: 'image.png',
      path: 'https://example.com/image.png',
    }
  ],
});

Attachment Limitations:

  • Maximum 10 attachments per email (Usesend API limit)
  • All content is automatically converted to base64 format
  • File size limits depend on your Usesend account plan

Validation Features

The transport includes comprehensive validation:

Email Address Validation

  • Validates all email addresses (from, to, cc, bcc, replyTo)
  • Supports display name format: "Name <[email protected]>"
  • Provides clear error messages for invalid email formats
// ✅ Valid formats
"[email protected]"
"John Doe <[email protected]>"
["[email protected]", "[email protected]"]

// ❌ Invalid - will throw error
"invalid-email"
"user@"
"@example.com"

Required Fields Validation

  • Validates that from, to, and subject are provided
  • Ensures at least one content type (text or html) is present

Content Handling

  • Automatically generates text version from HTML if only HTML is provided
  • Uses text content for both formats if only text is provided
  • Supports both text and HTML when both are provided

Error Handling

The transport provides detailed error messages with helpful hints:

Validation Errors

Invalid email address in "to": "invalid-email".
Please provide a valid email address (e.g., [email protected] or "Name <[email protected]>").

API Errors

  • 400 Bad Request: Hints about invalid formats, missing fields, or malformed data
  • 401 Unauthorized: Authentication failed, check your API key
  • 403 Forbidden: API key lacks permissions
  • 429 Rate Limited: Too many requests, wait before retrying
  • 5xx Server Error: Usesend service issues

Domain Verification Errors

Usesend API Error (BAD_REQUEST): Domain: example.com of from email is wrong.
Use the domain verified by useSend

TypeScript Support

Full TypeScript definitions are included:

import { UsesendTransport, UsesendTransporterOptions } from 'usesend-nodemailer';

const options: UsesendTransporterOptions = {
  apiKey: 'your_api_key',
  apiUrl: 'https://custom-endpoint.com', // optional
};

const transport = UsesendTransport.makeTransport(options);

API Reference

UsesendTransport.makeTransport(options)

Creates a new Usesend transport instance.

Parameters:

  • options.apiKey (string, required): Your Usesend API key
  • options.apiUrl (string, optional): Custom API endpoint URL

Returns: Transport instance compatible with Nodemailer

transport.send(mail, callback)

Sends an email (called automatically by Nodemailer's sendMail method).

Parameters:

  • mail: MailMessage object from Nodemailer
  • callback: Callback function with error and response info

Requirements

  • Node.js 14.0 or higher
  • Nodemailer ^6.10.0 (peer dependency)

License

MIT

Contributing

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

Support

For issues and questions: