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

@growth-labs/email

v0.5.0

Published

Thin transactional email transport for Cloudflare Workers.

Downloads

628

Readme

@growth-labs/email

Thin transactional email transport for Cloudflare Workers.

Use this package when you need to send a one-off email from a Worker right now, without subscriber state, queueing, tracking, or newsletter flows.

If you need campaigns, digests, subscriber management, unsubscribe/preferences, or queue-based delivery, use @growth-labs/mailer instead.

When to use this vs @growth-labs/mailer

Use @growth-labs/email for transactional, one-off sends:

  • Password-reset emails
  • Purchase receipts and order confirmations
  • Magic-link authentication emails
  • "Your download is ready" notifications

Use @growth-labs/mailer for newsletter and campaign workflows:

  • Newsletter subscription flows (double opt-in, confirmation)
  • Campaign sends to subscriber lists
  • Open/click tracking
  • Unsubscribe handling
  • Subscriber preference management

The two packages intentionally do not share infrastructure. email writes immediately via env.SEND_EMAIL. mailer uses Cloudflare Queues for batched campaign delivery, D1 for subscriber state, and injects routes for subscribe/confirm/unsubscribe/preferences/webhooks/tracking.

If a consumer has declared both packages and is unsure, the rule of thumb is: if the email goes to exactly one person as a direct response to an action they just took, use email. Otherwise, use mailer.

API

Structured Cloudflare Email Sending:

import { sendEmail } from '@growth-labs/email'

const result = await sendEmail(env, {
  from: { email: '[email protected]', name: 'Example' },
  to: '[email protected]',
  cc: '[email protected]',
  subject: 'Your login code',
  text: 'Your code is 123456',
  html: '<p>Your code is <strong>123456</strong></p>',
  headers: {
    'X-Workflow': 'login-code',
  },
})

Provider-neutral raw MIME:

import { send } from '@growth-labs/email'

const result = await send({
  provider: 'fastmail',
  credentials: {
    provider: 'fastmail',
    jmapToken: env.FASTMAIL_JMAP_TOKEN,
  },
  rfc822Bytes: canonicalMimeBytes,
  envelopeFrom: '[email protected]',
  envelopeTo: ['[email protected]'],
})

Providers

Structured sends use Cloudflare Email Service via env.SEND_EMAIL. If the binding is missing, sendEmail() throws.

Raw MIME sends through sendEmail() use Cloudflare's official REST endpoint:

await sendEmail(env, {
  from: { email: '[email protected]', name: 'Support' },
  to: '[email protected]',
  rawMime: canonicalMimeBytes,
  rawMessageId: '<[email protected]>',
})

For raw MIME delivery through sendEmail(), env must include CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN.

Provider-neutral raw MIME sends use send():

  • provider: 'cloudflare' sends through Cloudflare's raw MIME REST endpoint using { provider: 'cloudflare', accountId, apiToken }.
  • provider: 'fastmail' sends through Fastmail JMAP using { provider: 'fastmail', jmapToken }. Optional overrides are available for jmapSessionUrl, accountId, identityId, sentMailboxId, and draftsMailboxId.
  • provider: 'google' credentials are typed for future Workspace support, but the transport currently returns google_not_implemented.

The MIME message should include the display headers (From, To, Subject, Message-ID, Content-Type, and threading headers as needed); envelopeFrom and envelopeTo control the SMTP envelope.

Scope

  • Immediate transactional delivery
  • Single or multiple recipients
  • Plain text required and HTML optional for structured sends
  • CC, BCC, reply-to, custom headers, and attachments
  • Raw MIME delivery for canonical RFC 5322 messages
  • Provider-neutral raw MIME delivery through Cloudflare or Fastmail JMAP
  • { success, provider, messageId?, error?, errorCode? } result
  • { providerAcceptedAt, providerMessageId, errorCode, errorDetail } result for send()

Non-Goals

  • No Astro integration
  • No injected routes or middleware
  • No D1 state
  • No queue fan-out
  • No campaigns or digests
  • No unsubscribe or preferences flows
  • No tracking pixels or click rewriting