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

@msgly/smtp

v1.4.0

Published

SMTP + IMAP adapter for Msgly — works with Yahoo, Zoho, Fastmail, or any custom mail server

Readme

@msgly/smtp

SMTP + IMAP adapter for Msgly. Works with Yahoo, Zoho, Fastmail, iCloud, AOL, or any custom mail server — anything that speaks SMTP for sending and IMAP for receiving.

Node-only. Unlike the other msgly adapters, this one cannot run on Edge runtimes or in a browser: SMTP and IMAP are raw TCP/TLS protocols that fetch cannot speak. It depends on nodemailer and imapflow.

📖 Docs & channel reference: https://ayushjain070401.github.io/msgly/

npm install @msgly/core @msgly/smtp

Quick start

import { createHub } from '@msgly/core';
import { createSmtpAdapter } from '@msgly/smtp';

const smtp = createSmtpAdapter({
  emailAddress: '[email protected]',
  displayName: 'Acme Support',
  smtp: {
    host: 'smtp.mail.yahoo.com',
    port: 465,
    secure: true,
    auth: { user: '[email protected]', pass: process.env.YAHOO_APP_PASSWORD! },
  },
  imap: {
    host: 'imap.mail.yahoo.com',
    port: 993,
    secure: true,
    auth: { user: '[email protected]', pass: process.env.YAHOO_APP_PASSWORD! },
  },
});

const hub = createHub().register(smtp);

await hub.connect({ throwOnFailure: true });  // verifies the SMTP login
await hub.start();                            // begins polling IMAP

hub.on('message', async (msg) => {
  await hub.send({
    channel: 'smtp',
    account: msg.account,
    contact: msg.contact,
    content: { type: 'text', text: `You wrote: ${msg.content.text}` },
    metadata: {
      subject: msg.metadata?.subject,
      messageId: msg.metadata?.messageId,   // threads the reply
    },
  });
});

App-specific passwords

Every major provider requires an app-specific password once 2FA is enabled — your normal account password will be rejected with 535.

| Provider | SMTP | IMAP | Where to generate | | --- | --- | --- | --- | | Yahoo | smtp.mail.yahoo.com:465 | imap.mail.yahoo.com:993 | Account Security → Generate app password | | Zoho | smtp.zoho.com:465 | imap.zoho.com:993 | My Account → Security → App Passwords | | Fastmail | smtp.fastmail.com:465 | imap.fastmail.com:993 | Settings → Privacy & Security → App Passwords | | iCloud | smtp.mail.me.com:587 | imap.mail.me.com:993 | appleid.apple.com → App-Specific Passwords | | AOL | smtp.aol.com:465 | imap.aol.com:993 | Account Security → Generate app password | | Custom | your server | your server | — |

Use port 465 with secure: true for implicit TLS, or 587 with secure: false for STARTTLS.

Receiving mail

There is no webhook — IMAP is a polled connection. hub.start() begins polling (default every 60s, set pollIntervalMs), and handleWebhook() triggers a single poll if you'd rather drive it from your own scheduler.

On a cold start the adapter reads only new mail, never the whole mailbox. Pass a stateStore to persist the UID cursor so a restart resumes exactly where it stopped:

import Redis from 'ioredis';

const smtp = createSmtpAdapter({ ...cfg, stateStore: new Redis() });

Send-only mode

Omit imap entirely for transactional mail or campaigns. start() becomes a no-op and no inbound messages are produced.

Attachments

Opt in per adapter, matching the other email adapters:

const smtp = createSmtpAdapter({
  ...cfg,
  attachments: { enabled: true, maxSizeBytes: 25 * 1024 * 1024 },
});

const ref = await smtp.uploadMedia({
  data: await readFile('invoice.pdf'),
  mimeType: 'application/pdf',
  filename: 'invoice.pdf',
});

await hub.send({
  channel: 'smtp',
  /* ... */
  content: { type: 'text', text: 'Invoice attached.' },
  attachments: [{ mediaRef: ref, filename: 'invoice.pdf', mimeType: 'application/pdf' }],
});

Inbound attachments are lazy — you get filename, MIME type, and size, and the bytes stay on the IMAP server until you call downloadMedia(ref).

Set contentId on an attachment and reference it as cid: in an HTML body for embedded images.

Rate limits

Consumer mail providers meter aggressively, usually per hour or per day. The default for campaigns is a deliberately slow 2/s — raise it only if your provider documents a higher ceiling:

await hub.sendBulk({ channel: 'smtp', /* ... */, rateLimit: { perSecond: 10 } });

License

MIT