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

@ghostpaw/email

v0.2.2

Published

Standalone IMAP/SMTP email engine for Node.js — SQLite local cache, threading, sync, zero dependencies, with a built-in LLM tool facade

Downloads

272

Readme

@ghostpaw/email

npm node license dependencies TypeScript

A standalone email engine for Node.js, built on SQLite.

Email treats IMAP sync, SMTP send, local caching, threading, search, and transport errors as one coherent model instead of a grab bag of protocol adapters. It ships as a single prebundled blob with zero runtime dependencies, designed for three audiences at once: human developers working directly in code, LLM agents operating through a structured soul / tools / skills runtime, and agent operators who want a ready-to-use email CLI binary without writing any wiring code.

Install

npm install @ghostpaw/email        # as a library
npm install -g @ghostpaw/email     # as a global CLI
npx @ghostpaw/email --help         # one-off, no install needed

Requires Node.js 24+ (uses the built-in node:sqlite module).

Quick Start

import { Mailbox } from '@ghostpaw/email';

const mailbox = new Mailbox({
  imap: { host: 'imap.example.com', port: 993, tls: true },
  smtp: { host: 'smtp.example.com', port: 465, tls: true },
  auth: { user: '[email protected]', pass: 'secret' },
  storage: 'mail.db',
});

await mailbox.connect();

const folders = mailbox.read.folders();
await mailbox.network.sync();
const messages = mailbox.read.messages('INBOX', { limit: 20 });

await mailbox.write.send({
  to: [{ address: '[email protected]' }],
  subject: 'Hello',
  text: 'Sent from @ghostpaw/email.',
});

await mailbox.disconnect();

connect() opens the SQLite database, initialises the schema, upserts the account, and authenticates the IMAP session — one call does everything.

The Model

Seven stored concepts and three derived ones:

| Concept | Purpose | |---|---| | Account | One email identity with IMAP/SMTP connection config | | Folder | One IMAP mailbox path with sync metadata and role detection | | Message | A locally cached email header record with flags, labels, and envelope | | Body | The decoded text/html content and raw RFC 2822 bytes of one message | | Attachment | A decoded MIME part with on-demand binary fetch | | SyncLog | A record of one completed sync pass per folder | | Thread | A JWZ conversation tree derived from References/In-Reply-To headers |

The model means each kind of mail state has its own home:

| What it looks like | What it actually is | |---|---| | An email inbox | A Folder with role: 'inbox' and synced messages | | A conversation | A Thread computed from References and In-Reply-To chains | | An unread email | A Message without \Seen in its flags array | | A starred email | A Message with \Flagged in its flags | | A PDF attached to a message | An Attachment with metadata from BODYSTRUCTURE and data fetched on demand | | "Sync found 12 new messages" | A SyncLog row recording strategy, counts, and duration |

State is derived, not toggled. Thread IDs are computed from header chains at sync time, folder roles are detected from IMAP special-use attributes, and attachment metadata is extracted from BODYSTRUCTURE — all materialised during sync, never stored as manual status fields.

Two Audiences

Human developers

Use the Mailbox class with typed read, write, and network surfaces for direct-code access to every mail operation:

import { Mailbox } from '@ghostpaw/email';

const mailbox = new Mailbox(config);
await mailbox.connect();

const threads = mailbox.read.threads('INBOX', { limit: 20 });
const detail = await mailbox.read.getMessage('INBOX', uid);
await mailbox.write.reply('INBOX', uid, { text: 'Acknowledged.' });
await mailbox.write.archive('INBOX', [uid]);

See HUMAN.md for the full human-facing guide with worked examples.

LLM agents

Use the tools, skills, and soul namespaces for a structured runtime surface designed to minimise LLM cognitive load:

import { skills, soul, tools } from '@ghostpaw/email';

// 5 intent-shaped tools covering the full mailbox lifecycle
const allTools = tools.emailTools;
const readTool = tools.getEmailToolByName('mail_read');

// 8 reusable workflow skills for multi-step scenarios
const triageSkill = skills.getEmailSkillByName('triage-inbox');

// Thinking foundation for system prompts
const systemPrompt = soul.renderEmailSoulPromptFoundation();

Every tool returns a structured result with outcome, summary, entities, and nextSteps — no thrown exceptions to parse, no ambiguous prose.

See LLM.md for the full AI-facing guide covering soul, tools, and skills.

CLI (bash)

The package ships as a standalone email binary. Accounts are stored in ~/.config/email/accounts.json and every command accepts --json for machine-readable output.

# Add an account once
email account add --name work \
  --imap-host imap.example.com --smtp-host smtp.example.com \
  --user [email protected] --pass secret

# Then use it
email sync                              # pull latest from server
email read                             # check inbox
email search "invoice"                 # FTS5 search
email compose send --to [email protected] --subject "Hi" --body "Hello"

# Machine-readable output for agents and scripts
email read queue --json | jq '.entities[].title'
echo "body text" | email compose send --to [email protected] --subject "Hi"

All commands return the same { outcome, summary, entities, nextSteps } shape as the tool layer, with consistent exit codes (0 success, 1 user error, 2 config, 3 auth, 4 network, 5 tool error).

See SKILL.md for the complete CLI reference for agent operators and Claude Code / OpenClaw users.

Tools

Five tools shaped around operator intent, not raw protocol operations:

| Tool | What it does | |---|---| | mail_read | Read folder lists, message queues, threads, bodies, attachments, or raw EML | | mail_search | FTS5 local search or IMAP SEARCH on the server | | mail_compose | Send, reply, forward, save/update/send drafts | | mail_organize | Flags, labels, copy, move, archive, trash, junk, folder management | | mail_sync | Connect, disconnect, reconnect, sync, refresh folders, watch |

Key Properties

  • Zero runtime dependencies. Only node:sqlite, node:tls, node:net, node:zlib, node:crypto (built into Node 24+).
  • Single prebundled blob. One ESM + one CJS entry in dist/. No subpath exports, no code splitting.
  • Pure SQLite storage. FTS5 full-text search, six tables, and deterministic derived reads. Mailbox creates and manages its own DatabaseSync instance.
  • Full IMAP engine. Streaming tokenizer, response parser, COMPRESS=DEFLATE, IDLE (RFC 2177), CONDSTORE/QRESYNC (RFC 7162), XOAUTH2/OAUTHBEARER.
  • Full SMTP client. TLS/STARTTLS/plaintext, PLAIN/LOGIN/XOAUTH2, dot stuffing, APPEND to Sent after send.
  • Fetch-on-demand bodies. Initial sync pulls headers and BODYSTRUCTURE only. Message bodies and attachment bytes are fetched when actually read.
  • JWZ threading. Conversation trees computed from References/In-Reply-To headers, with depth-ordered rendering and cross-folder support.
  • Intention-shaped writes. send, reply, forward, archive, trash, saveDraft, sendDraft — operations that say what happened, not generic CRUD.
  • Additive AI runtime. soul for posture, tools for actions, skills for workflow guidance — all optional, all structured.
  • Colocated tests. Every non-type module has a colocated .test.ts file. The documented behaviour is backed by executable coverage.

Package Surface

import {
  Mailbox,      // porcelain class — the primary entry point
  initSchema,   // schema setup (called automatically by Mailbox.connect())
  read,         // read surface factory
  write,        // write surface factory
  network,      // network surface factory
  tools,        // LLM tool definitions + registry
  skills,       // LLM workflow skills + registry
  soul,         // thinking foundation for system prompts
} from '@ghostpaw/email';

All domain and runtime types are also available at the root for TypeScript consumers:

import type {
  EmailConfig,
  AuthConfig,
  EmailReadSurface,
  EmailWriteSurface,
  EmailNetworkSurface,
  EmailToolDefinition,
  EmailToolResult,
  EmailSkill,
  EmailSoul,
  ComposeInput,
  ReplyInput,
  ForwardInput,
  Message,
  MessageDetail,
  Thread,
  Folder,
  Attachment,
  AttachmentMeta,
  SyncResult,
  WatchEvent,
} from '@ghostpaw/email';

Documentation

| Document | Audience | |---|---| | SKILL.md | Agent operators and Claude Code users running email as a bash tool | | HUMAN.md | Human developers using the Mailbox API with read / write / network | | LLM.md | Agent builders wiring soul, tools, and skills into LLM systems | | docs/README.md | Architecture overview: model, invariants, protocol boundaries, source layout | | docs/entities/ | Per-entity manuals with schema, operations, and invariants |

Development

npm install
npm test            # node:test runner
npm run typecheck   # tsc --noEmit
npm run lint        # biome check
npm run build       # ESM + CJS + declarations via tsup

The repo is pinned to Node 24.14.0 via .nvmrc / .node-version / .tool-versions / mise.toml / Volta. Use whichever version manager you prefer.

Support

If this package helps your project, consider sponsoring its maintenance:

GitHub Sponsors


AnonyfoxMIT License