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

emailservicehub

v0.1.20

Published

CLI client for Email Service Hub — manage SES and NameCheap from the terminal

Readme

emailservicehub

CLI client for Email Service Hub. Manage AWS SES and NameCheap DNS from the terminal.

Website: https://www.emailservicehub.com

Install

# Run without installing
npx esh --help
npx emailservicehub --help

# Or install globally
npm install -g emailservicehub
esh --help

The binary is available as both esh (short) and emailservicehub (long).

Quick start

# 1. Authenticate — opens your browser to authorize the CLI
esh login
esh whoami

# 2. Store your NameCheap API credentials on your ESH account
esh nc key set --api-key <key> --api-user <user>

# 3a. Minimal: just register the domain identity in SES so SMTP can use it
#     (writes only the _amazonses verification TXT — safe alongside NameCheap
#     email forwarding / Private Email)
esh ses domain register example.com

# 3b. Full setup: verification + DKIM + SPF + DMARC, written to NameCheap DNS,
#     then blocks until SES reports the domain as Verified (pass --no-wait
#     for fire-and-forget). MAIL FROM subdomain is opt-in (--mail-from)
#     because it submits an MX that disables NameCheap email forwarding on
#     the apex.
esh ses domain add example.com

# 4. Send a test email once verification completes
esh ses send --from [email protected] --to [email protected] \
  --subject "Hi" --message "Hello from esh"

Local development against the dev server

If you're hacking on the Next.js app and the CLI at the same time, run the CLI via pnpm cli:dev from the repo root — it builds the CLI in watch mode and automatically targets http://localhost:3000 without needing --dev:

# Run any esh command against the local dev server
pnpm cli:dev ses identities
pnpm cli:dev ses domain add example.com

The auto---dev behavior triggers whenever the CLI is invoked under the cli:dev script; pass --prod to override it, or --port <n> to point at a dev server on a non-default port.

Not logged in? Use local credentials instead

By default the CLI talks to the Email Service Hub API, which holds your AWS and NameCheap credentials server-side — esh login is the normal happy path. If you'd rather not sign up or store credentials on a hosted service, pass --local to skip the ESH API entirely and drive AWS and NameCheap directly from credentials on your own machine:

# AWS SES calls use ~/.aws/credentials (standard AWS SDK resolution)
# NameCheap calls use NAMECHEAP_API_KEY + NAMECHEAP_API_USER env vars
export NAMECHEAP_API_KEY=abc123...
export NAMECHEAP_API_USER=myuser

esh --local ses identities
esh --local nc domains list
esh --local ses domain add example.com

When you run a command without being logged in, the CLI will remind you of this option before it errors out. See Local mode below for the full list of env vars and flags.

Global flags

These flags work on every command:

| Flag | Description | | --- | --- | | --json | Emit raw JSON instead of formatted tables (good for scripting) | | --no-color | Disable ANSI colors | | --verbose | Show HTTP request/response details | | --profile <name> | Use a named profile from ~/.esh/config.json | | --dev | Target the local Next.js dev server (http://localhost:3000) instead of production | | --prod | Force the production ESH API (https://emailservicehub.com) — useful to override the auto---dev triggered by pnpm cli:dev | | --port <number> | Override the dev-server port (implies --dev) | | --local | Skip the ESH API entirely and call AWS + NameCheap directly from your machine using local credentials (see Local mode) | | --aws-profile <name> | AWS named profile to load from ~/.aws/credentials when using --local. Defaults to $AWS_PROFILE or default. | | --aws-region <region> | AWS region for SES calls in --local mode. Defaults to $AWS_REGION, then $AWS_DEFAULT_REGION, then us-east-1. | | -V, --version | Print the CLI version | | -h, --help | Print help for any command (works on every subcommand) |


Authentication

| Command | Description | | --- | --- | | esh login | Authenticate via the browser. Opens https://emailservicehub.com/cli/auth in your default browser, waits for you to approve, then stores a per-user API key in ~/.esh/config.json. | | esh login --token <key> | Non-interactive login for CI/scripts. Stores the supplied API key directly and verifies it against the server. | | esh logout | Remove stored credentials for the active profile. | | esh whoami | Show the currently authenticated user's email and role. | | esh status | Show config file location, active profile, API URL, and auth state. |

The browser flow spins up an ephemeral HTTP server on a random localhost port, prints the authorization URL it's about to open, and waits for you to press Enter or Space before actually opening the browser (Ctrl-C cancels). Once you approve in the browser, the page delivers a freshly-minted API key back to the local server and the CLI stores it. The key is hashed server-side (SHA-256) before storage; only the plaintext copy in your ~/.esh/config.json exists anywhere in the clear. When stdin isn't a TTY (piped input, CI), the keypress gate is skipped and the browser opens immediately.


esh ses — AWS SES

| Command | Description | | --- | --- | | esh ses stats | Show SES quotas, 24h send counts, and delivery rate. | | esh ses identities | List all verified SES identities (domains and email addresses) with DKIM state. | | esh ses activity [-l, --limit <n>] | Show recent email activity. Default limit: 10. | | esh ses domain register <domain> | Minimally register a domain with SES so it can be used as the From: address on the AWS SMTP endpoint. Writes only the _amazonses verification TXT — no DKIM, SPF, DMARC, or MAIL FROM. Re-runs are safe: the output reports whether the domain was already verified, still pending, previously failed, or freshly initiated. Use --no-dns to print the record for manual entry. | | esh ses domain add <domain> | Add a domain to SES end-to-end: registers the identity, enables DKIM, configures NameCheap DNS (verification TXT + 3 DKIM CNAMEs + SPF + DMARC), then waits for SES to report verification + DKIM as Success. MAIL FROM subdomain is opt-in — pass --mail-from to enable it (it adds an apex-level MX that disables NameCheap email forwarding). Pass --no-wait to skip the verification poll. See flags below. | | esh ses email add <address> | Request SES verification for an email address. SES sends a confirmation link to the address; the recipient must click it to finish. Re-runs are safe — the output reports whether the address was already verified, still pending, previously failed, or freshly requested. | | esh ses send | Send a test email. See required flags below. |

esh ses domain register <domain> flags

| Flag | Description | | --- | --- | | --no-dns | Skip the NameCheap write — call SES VerifyDomainIdentity only and print the TXT record for manual entry. |

Use register when you only need to send mail through the AWS SMTP endpoint and want minimal blast radius: it adds only the _amazonses TXT and never submits an MX, so it is safe alongside NameCheap email forwarding, Private Email, or any other apex mail product. For full deliverability hardening (DKIM/SPF/DMARC), follow up with esh ses domain add once you've confirmed nothing else on the domain depends on the existing apex MX configuration.

esh ses domain add <domain> flags

| Flag | Description | | --- | --- | | --no-dns | Skip NameCheap DNS setup — only initiate SES verification and print the records for manual entry. | | --no-spf | Do not add an SPF (v=spf1 include:amazonses.com ~all) TXT record. | | --no-dmarc | Do not add a DMARC (p=none, with rua=) TXT record. | | --mail-from | Opt in to a custom mail.<domain> MAIL FROM subdomain (MX + SPF TXT). Off by default because the MX submission flips NameCheap's zone-level EmailType from FWD (or OX) to MX, which disables NameCheap email forwarding and Private Email on the apex. Enable only on domains where you don't use NameCheap-hosted inbound mail. | | --no-wait | Skip the verification poll. By default the command blocks for up to 2 minutes waiting for SES to mark domain verification + DKIM (and MAIL FROM, if --mail-from was passed) as Success. |

The command preserves existing NameCheap records, merging only where host+type collides. Existing TXT records that would be replaced by SPF/DMARC are surfaced as warnings before the write. MX records are submitted to NameCheap with the priority split from the host (the CLI auto-parses zone-file format like 10 feedback-smtp.us-west-2.amazonses.com).

Re-runs are safe: the output distinguishes "already verified", "already pending", and freshly-initiated states based on what SES reported before this invocation, and the wait phase exits early if SES already considers everything verified.

Coexistence with NameCheap email products. NameCheap stores a zone-level EmailType (FWD for Email Forwarding, OX for Private Email, MX for custom mail servers) that drives the apex MX records server-side — those MX records do not appear in nc dns list output. The CLI flips EmailType to MX only when the records it submits include an MX, so DKIM/SPF/DMARC are safe to add to a forwarding-enabled domain. --mail-from does submit an MX (on mail.<domain>) and will switch EmailType to MX, disabling NameCheap forwarding/Private Email on the apex — that is why MAIL FROM is opt-in. esh ses domain add --mail-from is the only domain flow that touches MX; the rest are MX-free and forwarding-safe.

esh ses send flags

| Flag | Description | | --- | --- | | --from <email> | Required. Sender address (must be a verified SES identity). | | --to <email> | Required. Recipient address. | | --subject <text> | Required. Email subject. | | --message <text> | Required. Plain-text body. | | --html <html> | Optional HTML body. |


esh nc — NameCheap

By default, NameCheap commands read your API credentials from your ESH account (set them once via esh nc key set). When invoked with --local, they instead read from environment variables — see Local mode.

Key management

| Command | Description | | --- | --- | | esh nc key show (default) | Show the masked NameCheap API key stored in your ESH account. Also runs as esh nc key. | | esh nc key set --api-key <key> --api-user <user> [--client-ip <ip>] | Store your NameCheap API credentials. --client-ip defaults to the ESH server's public IP (the one NameCheap whitelists). | | esh nc key test | Test the currently-stored NameCheap credentials by making a read-only API call and reporting pass/fail with an actionable hint on failure. | | esh nc key test --api-key <key> --api-user <user> [--user-name <name>] [--client-ip <ip>] | Test candidate credentials without storing them. Useful before esh nc key set to verify a key is valid, API access is enabled, and the source IP is whitelisted. Exits non-zero on failure for scripting. |

Domains

| Command | Description | | --- | --- | | esh nc domains list (default) | List all domains on your NameCheap account. Also runs as esh nc domains. | | esh nc domains check <domain> | Check whether a domain is available for registration. |

DNS

| Command | Description | | --- | --- | | esh nc dns list <domain> | List all DNS records for a domain. | | esh nc dns set <domain> --type <type> --host <host> --value <value> [--ttl <ttl>] | Add or update a DNS record. Replaces any existing record with the same host+type; preserves all others. TTL defaults to 1800. | | esh nc dns delete <domain> --type <type> --host <host> | Delete a DNS record by host+type. |


esh config — CLI configuration

| Command | Description | | --- | --- | | esh config show | Print the full config file contents. | | esh config get <key> | Get a single config value. Valid keys: api-url, token, email. | | esh config set <key> <value> | Set a config value. Valid keys: api-url, token, email. | | esh config reset | Reset the config file to defaults (default profile pointing at https://emailservicehub.com). |

Credentials are stored in ~/.esh/config.json (permissions 0600). Each profile keeps its own apiUrl, token, and email, switchable with the global --profile flag.


Local mode

The CLI has two operating modes:

  • Remote mode (default) — commands call the Email Service Hub API, which holds your AWS and NameCheap credentials server-side. This is the recommended path and is what esh login sets up. Everything in the esh ses and esh nc command trees works out of the box once you're logged in.
  • Local mode (--local, opt-in) — the CLI skips the ESH API entirely and talks to AWS SES and the NameCheap XML API directly from your machine, using credentials it finds on your local system. No ESH login is required; --local works even when you're logged out.

Local mode is the right fit when you want to run the CLI against credentials you already manage yourself — e.g., on a workstation with ~/.aws/credentials already configured, or in CI where secrets come in as environment variables — without round-tripping through the hosted API.

You don't need to think about local mode unless you want to. When you run a command without being logged in, the CLI will print a one-line hint pointing you at both options (esh login or esh --local …) so you can pick the one that fits your setup. Remote mode remains the default in every other case.

AWS credentials (SES commands)

In --local mode, AWS calls use the standard AWS SDK credential-provider chain, in this order:

  1. AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN environment variables
  2. A named profile from ~/.aws/credentials (and ~/.aws/config)
  3. AWS SSO / IAM role profiles configured in ~/.aws/config

| Setting | Source | Default | | --- | --- | --- | | AWS profile | --aws-profile <name>, then $AWS_PROFILE | default | | AWS region | --aws-region <region>, then $AWS_REGION, then $AWS_DEFAULT_REGION | us-east-1 |

Example:

# Use the 'staging' profile from ~/.aws/credentials
esh --local --aws-profile staging --aws-region us-west-2 ses identities

# Or via env vars
AWS_PROFILE=staging AWS_REGION=us-west-2 esh --local ses identities

NameCheap credentials (nc commands)

In --local mode, NameCheap commands read credentials from environment variables:

| Env var | Required | Description | | --- | --- | --- | | NAMECHEAP_API_KEY | yes | Your NameCheap API key (Profile → Tools → API Access) | | NAMECHEAP_API_USER | yes | Your NameCheap API user — usually your NameCheap account username | | NAMECHEAP_USERNAME | no | NameCheap UserName parameter. Defaults to $NAMECHEAP_API_USER. | | NAMECHEAP_CLIENT_IP | no | IP address whitelisted in NameCheap's API settings. If unset, the CLI auto-detects your public IP via a public echo service and falls back to 127.0.0.1. Override per-invocation with --client-ip. |

NameCheap's API requires that the caller's IP is explicitly whitelisted in your account settings. If local-mode calls fail with Invalid request IP, set NAMECHEAP_CLIENT_IP to the IP you whitelisted (usually your workstation's public IP).

Example:

export NAMECHEAP_API_KEY=abc123...
export NAMECHEAP_API_USER=myuser

esh --local nc domains list
esh --local nc dns list example.com
esh --local nc dns set example.com --type TXT --host @ --value "v=spf1 include:amazonses.com ~all"

Mixed commands

esh ses domain add touches both AWS and NameCheap. In --local mode, both credential sources must be available: AWS for the SES calls, NameCheap env vars for the DNS writes. Pass --no-dns to skip the NameCheap side entirely if you only have AWS credentials locally.

export NAMECHEAP_API_KEY=abc123...
export NAMECHEAP_API_USER=myuser

esh --local ses domain add example.com

JSON mode

Every command honors --json for machine-readable output, making the CLI scriptable:

# Pipe identities into jq
esh --json ses identities | jq '.identities[] | select(.verificationStatus == "Success") | .identity'

# Grab just the verification token when registering a domain without touching DNS
esh --json ses domain register example.com --no-dns | jq -r .verificationToken

Help

Every command and subcommand supports --help:

esh --help
esh ses --help
esh ses domain register --help
esh ses domain add --help
esh nc dns set --help