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

@cool-ai/beach-transport-email

v0.2.0

Published

IMAP and SMTP transport adapters for Beach — the wire layer underneath @cool-ai/beach-channel-email.

Readme

@cool-ai/beach-transport-email

Home: cool-ai.org · Documentation: cool-ai.org/docs

IMAP and SMTP transport adapters for Beach. Wire layer only — connection management, polling, parsing, sending. Channel-shaped concerns (envelope translation, threading, the Missive part-bag) live in @cool-ai/beach-channel-email.

When to use this package directly

  • You are writing a custom email channel layered on a different missive shape.
  • You need to swap a formatter on the SMTP adapter without taking the whole channel package.
  • You are reimplementing parts of @cool-ai/beach-channel-email and only want the transport pieces.

If any of those does not match, use @cool-ai/beach-channel-email instead — it bundles these adapters with the canonical envelope-to-message translation and is what most consumers want.

Quickstart

import { ImapInboundAdapter, SmtpOutboundAdapter } from '@cool-ai/beach-transport-email';

const inbound = new ImapInboundAdapter({
  config: {
    host: 'imap.example.com',
    port: 993,
    secure: true,
    auth: { user: process.env.IMAP_USER!, pass: process.env.IMAP_PASS! },
  },
  pollIntervalMs: 60_000,
  uidState: {
    get: (mailbox) => redis.get(`beach-email:lastUid:${mailbox}`).then((v) => (v ? Number(v) : undefined)),
    set: (mailbox, uid) => { await redis.set(`beach-email:lastUid:${mailbox}`, String(uid)); },
  },
  onMessage: async (parsed) => {
    /* parsed is RFC 822-shaped — translate to a Missive in your channel layer */
  },
});

await inbound.start();

const outbound = new SmtpOutboundAdapter({
  host: 'smtp.example.com',
  port: 465,
  secure: true,
  auth: { user: process.env.SMTP_USER!, pass: process.env.SMTP_PASS! },
  from: '[email protected]',
});

await outbound.send({
  to: ['[email protected]'],
  subject: 'Hello',
  text: 'World',
});

What this package contains

  • ImapInboundAdapter — long-lived IMAP connection, configurable polling interval, UID-state callback, RFC 822 parsing via mailparser. Hands a ParsedInboundEmail to your onMessage callback.
  • SmtpOutboundAdapternodemailer transporter, single send(email) entry point. Owns the connection lifecycle.

That is the whole surface.

SMTP without authentication (trusted local relay)

SmtpTransportConfig.auth is optional. When omitted the adapter connects without authentication — suitable only for trusted-network local relays such as a Postfix daemon on localhost accepting unauthenticated connections from the loopback interface and signing outbound with DKIM via OpenDKIM.

const outbound = new SmtpOutboundAdapter({
  host: 'localhost',
  port: 25,
  secure: false,
  from: '[email protected]',
});

The adapter emits a startup warning when auth is absent so the opt-out is visible in logs. Never use this mode against a remote SMTP server — anything on the network can relay through it. The IMAP side still requires auth; only the SMTP path supports the no-auth shape.