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

preverification

v0.1.0

Published

Fast, SMTP-free email preverification CLI

Readme

verification

Fast, SMTP-free email pre-verification CLI. Takes a file full of emails (in any sensible separator format) and produces a verdict, a score, and the reasons behind each decision.

Why no SMTP?

SMTP probing works but drags along a bunch of real-world problems:

  • Greylisting and tarpitting make it slow.
  • Many providers (Google, Microsoft) lie — they return 250 OK on RCPT TO for any local part, defeating the point.
  • It hurts sender reputation and gets the probing IP blocklisted.
  • Most cloud and residential networks block outbound port 25.

Instead we combine several cheap signals:

  1. Syntax validation — pragmatic RFC-ish check that every real mailer enforces.
  2. Typo correction — e.g. gamil.comgmail.com, gmail.congmail.com. Uses Damerau-Levenshtein over a list of popular providers, plus TLD-only correction for custom domains.
  3. Domain validation — DNS-over-HTTPS against Google (dns.google) and Cloudflare (1.1.1.1), randomly picking a resolver per query.
  4. Catch-all detection — merged list of disposable providers plus heuristics on the domain's MX records (ImprovMX, forwardemail, etc. are strong catch-all signals).
  5. Light server verification — resolve the primary MX host to an IP and optionally TCP-connect to :25 without speaking SMTP. Confirms the host actually exists and a mail server is listening.
  6. Additional scoring — role-based locals (info@, admin@), free providers, plus-addressing, long locals, gibberish locals, digit runs, etc.

Each check contributes to a 0–100 score mapped to a valid / risky / invalid verdict.

Usage

npx verification@latest emails.txt

The input file can mix separators freely:

[email protected], [email protected]
[email protected]
[email protected];[email protected]

Options

| flag | description | | --- | --- | | -c, --concurrency <n> | parallel verifications (default 20) | | -f, --format <fmt> | pretty | json | jsonl | csv | | -o, --output <path> | write to a file instead of stdout | | -e, --export <path> | export a list of verified emails (normalized, one per line) | | --no-tcp | skip the TCP :25 reachability probe (DNS only) | | --tcp-timeout <ms> | TCP connect timeout (default 2500) | | --doh-timeout <ms> | DoH query timeout (default 3000) | | --min-score <n> | only print results at or above this score | | --only <verdict> | only print results with this verdict |

Examples

# pretty output, default
verification list.txt

# CSV export for a spreadsheet
verification list.txt -f csv -o report.csv

# JSON-lines for piping into jq
verification list.txt -f jsonl | jq 'select(.verdict == "risky")'

# only keep valid addresses
verification list.txt --only valid -f jsonl > clean.jsonl

Scoring reference

Every email starts at 100 and subtracts:

| signal | penalty | | --- | --- | | typo suggested | −15 | | no MX records | −25 | | disposable domain | −60 | | catch-all (high confidence) | −20 | | catch-all (medium confidence) | −10 | | role-based local | −12 | | plus-addressing | −3 | | long local (>30) | −5 | | gibberish local | −15 | | 6+ consecutive digits in local | −5 | | MX host does not resolve | −20 | | MX reachable on TCP :25 | +3 |

Thresholds: >=75 valid, >=40 risky, otherwise invalid. Hard fails (invalid syntax, NXDOMAIN) immediately score 0.