-
Hunter-level checks (regex → DNS → SMTP + catch-all detection)
- Go → AfterShip
email-verifier
: feature-rich, 100 k+ downloads/month, Docker-ready, still actively patched. (github.com) - Ruby →
Truemail
: the only gem that still handshakes over SMTP and handles grey-listing well. (github.com) - Rust →
check-if-email-exists
: fastest CLI/micro-service; ships an HTTP mode so every stack can call it. (crates.io) - Python →
validate_email
: long-running, PyPI >9 M downloads; portable but slower than Go/Rust. (pypi.org)
- Go → AfterShip
-
99 % of signup forms only need syntax + MX + disposable blocking—use:
- Ruby →
valid_email2
(monthly releases). (rubygems.org) - Node →
node-email-verifier
(ESM, no native deps). (npmjs.com) - Go →
truemail-go
(same API as the Ruby gem, no SMTP). (github.com)
- Ruby →
-
If port 25 is blocked in your cloud, run a tiny VPS or Docker task that exposes one of the Go/Rust verifiers over HTTP and call it from the rest of your stack.
Lang | Library | Last release | Syntax | MX | SMTP | Catch-all | Disposable list | Port override | Stars / DLs | Health |
---|---|---|---|---|---|---|---|---|---|---|
Go | AfterShip/email-verifier | v2.5 (Apr 2025) | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ | env SMTP_PORT |
1.4 k★ (pkg.go.dev) | Active |
truemail-go | v0.3 (Jan 2025) | ✔︎ | ✔︎ | ✘ | ✘ | optional | n/a | 250★ (github.com) | Active | |
go-email-validator | v1.6 (Nov 2023) | ✔︎ | ✔︎ | ✔︎ | partial | ✔︎ | code hook | 500★ (github.com) | Low churn | |
Ruby | Truemail | 3.3.1 (Apr 2024) | ✔︎ | ✔︎ | ✔︎ | ✔︎ | opt. | config.smtp_port |
1.2 k★ (github.com) | Active |
valid_email2 | 7.0.13 (May 2025) | ✔︎ | ✔︎ | ✘ | ✘ | ✔︎ | n/a | 6.6 M DL/mo (rubygems.org) | Very active | |
Node | email-verify | 0.2.1 (legacy) | ✔︎ | ✔︎ | ✔︎ | partial | ✘ | CLI -p |
355 DL/wk (aged) (npmjs.com) | Aging |
node-email-verifier | 2.0.2 (Sept 2024) | ✔︎ | ✔︎ | ✘ | ✘ | ✔︎ | n/a | 9 k DL/wk (npmjs.com) | Active | |
Python | validate_email | 1.3.0 (Feb 2025) | ✔︎ | ✔︎ | ✔︎ | ✔︎ | partial | param | 9 M DL/y (pypi.org) | Active |
Rust | check-if-email-exists | 0.8 (Oct 2024) | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ | env | 4.5 k★ (crates.io) | Active |
PHP | smtp-validate-email | 2.2 (Jul 2024) | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✘ | ctor param | 400★ (github.com) | Maintained |
C# | EmailValidator.NET | 1.6 (Dec 2024) | ✔︎ | ✔︎ | ✔︎ | limited | ✘ | ctor param | 28★ | Niche |
Java | JMail (in Simple-Java-Mail 8) | 2.0.0 (Jan 2025) | ✔︎ | opt | ✘ | ✘ | ✘ | n/a | 1 k★ | Active |
“Health” combines last-commit date, issue activity and download velocity.
- Full pipeline: Regex → typo hint → DNS/MX → SMTP handshake → catch-all probe → reachability score. (github.com)
- Extras: Gravatar, disposable list, role-account flag, typo suggestions (
gmail.com
←gamil.com
). - Why it wins in Go: fastest implementation, easy to wrap in a goroutine pool, Docker image provided.
- Configurable time-outs, safe-check (parallel MX probes), and built-in Rack micro-service so you can deploy it off your main Rails pods. (github.com)
- Handy CLI (
truemail --email [email protected]
) for ad-hoc audits. - Drawback: needs outbound port 25; on Heroku/Fly you must run it on a side-box.
- Ruby → valid_email2: ActiveModel plug-in, monthly disposable-domain updates, zero open ports. (rubygems.org)
- Go → truemail-go: syntax+MX only, but same API shape as the Ruby gem. (github.com)
- Node → node-email-verifier: ESM, small download, no native deps. (npmjs.com)
- Fastest raw throughput (≈70 k verifications/min on a 4-core box).
- Ships
--http
switch → instant micro-service for any stack. (crates.io)
Scenario | Best choice | Why |
---|---|---|
Bulk lists (20 k +/day) and you control port 25 | Go AfterShip/email-verifier or Rust check-if-email-exists behind HTTP | Both saturate 10–20 connections with <1 CPU core; easiest to scale horizontally. |
Rails app on Heroku where port 25 is blocked | Inline valid_email2 for syntax+MX, then call a tiny Docker of truemail or AfterShip on a $5 VPS over HTTP |
Keeps form latency <40 ms while still reaching inbox-level accuracy asynchronously. |
Fast client-side Node validate | node-email-verifier or deep-email-validator for syntax+MX; if you need SMTP, spawn a Go/Rust micro-service |
Node packages that do SMTP are mostly unmaintained and hit false-positives on IPv6. |
Low-risk internal tooling, .NET stack | EmailValidator.NET |
Lightweight; no unmanaged code; okay accuracy for corporate domains. |
Java monolith, need syntactic rigor but not SMTP | JMail |
Lexer-based parser passes RFC 5322 edge cases better than regexes. |
- AWS, GCP and many VPS hosts block or throttle outbound TCP 25 by default; you must file an exception request.
- Submission ports 587/465 usually require AUTH and so reject anonymous probes, so switching Truemail’s
smtp_port
may not help. - Using a separate, cheap VPS keeps any IP-reputation hits away from your production servers (and lets you rotate IPs if black-listed).
There’s no one-size-fits-all “best” library; pick based on accuracy vs. deployment friction:
- Need the absolute highest deliverability confidence? – Go AfterShip/email-verifier or Rust check-if-email-exists (wrap as a service).
- Need seamless Rails integration with decent accuracy? –
Truemail
(full) +valid_email2
(fast). - Just want to keep junk out of a sign-up form? – use syntax + MX validators (
valid_email2
,truemail-go
,node-email-verifier
) and skip SMTP entirely.
With the matrix above you can map feature depth, maintenance health, and networking constraints to the needs of your project and choose the library that really is “best” for your definition of best.