mxverify
v1.0.0
Published
Fast email verifier with no API key — checks syntax, disposable domains, role addresses, and live MX records. Tags each email valid / risky / invalid. Zero dependencies.
Downloads
182
Maintainers
Readme
mxverify
Fast email verification with no API key. Check syntax, disposable domains, role addresses, and live MX records — then get each email tagged valid / risky / invalid, with a reason. Zero dependencies, works offline except for the DNS lookups it needs.
No Hunter, no NeverBounce, no ZeroBounce account. No per-email billing. Just a tiny library + CLI you run yourself.
npx mxverify [email protected] [email protected] [email protected]VALID mx-ok [email protected]
RISKY role-based [email protected] [role]
INVALID disposable [email protected] [disposable]
3 checked — 1 valid, 1 risky, 1 invalidWhy
Most "is this email real?" tools want an API key and bill you per check. For a lot of jobs — cleaning a lead list, gating a signup form, deduping a CSV — you don't need a paid service. You need four cheap checks done locally:
- Syntax — is it a well-formed address? (RFC-ish, rejects what real mail servers reject)
- Disposable — is the domain a throwaway? (built-in blocklist of ~6,900 domains)
- Role-based — is it
info@/sales@/noreply@? (deliverable, but not a person — you decide) - MX records — can the domain actually receive mail? (live DNS lookup, with an A-record fallback per RFC 5321)
mxverify does exactly that and nothing else. It never contacts the mailbox (no SMTP probe by default), so it's safe to run against a prospect list without touching anyone.
Install
npm install mxverify # as a library
npm install -g mxverify # for the CLI, or just use npxLibrary
import { verifyEmail, verifyEmails } from 'mxverify';
const one = await verifyEmail('[email protected]');
// { email: '[email protected]', status: 'valid', reason: 'mx-ok',
// isRoleBased: false, isDisposable: false, mxHost: '...' }
// Verify a list — MX lookups are cached per-domain, so 2,000 emails
// across 40 domains only do 40 DNS queries.
const results = await verifyEmails(['[email protected]', '[email protected]', '[email protected]']);
const sendReady = results.filter((r) => r.status === 'valid');Status & reason
| status | meaning | reason values |
|-----------|---------|-----------------|
| valid | well-formed, not disposable, domain has MX | mx-ok |
| risky | deliverable but lower confidence | role-based, implicit-mx, mx-unknown |
| invalid | don't send | invalid-syntax, disposable, no-mx |
risky covers role addresses (info@), domains that receive mail via an A record instead of MX (RFC 5321), and lookups that couldn't complete (timeout / SERVFAIL) — those are flagged, not silently dropped.
Options
verifyEmail(email, {
checkMx: true, // set false for syntax + disposable only (instant, no DNS)
mxTimeoutMs: 5000, // per-domain DNS timeout
mxCache: new Map(), // share a cache across many calls
});CLI
mxverify [email protected] # single
mxverify --file emails.txt # one per line
cat emails.txt | mxverify --stdin # piped
mxverify --file emails.txt --json # machine-readable
mxverify --file emails.txt --fast # skip MX (syntax + disposable only)Exit code is non-zero when every input email is invalid — handy in CI/scripts.
How the MX check stays accurate
A naive MX lookup marks live domains (like google.com, whose MX answer some resolvers truncate) as dead. mxverify falls back to an A/AAAA lookup when there's no MX record — per RFC 5321 the A record is the implicit mail exchanger — and only returns no-mx when the domain resolves to nothing at all. It also sets public DNS resolvers as a fallback so it works on locked-down hosts where Node's default resolver fails.
Need emails to verify?
mxverify cleans a list you already have. If you need to build one, the verification logic here also ships inside an Apify actor that scrapes business emails from Google Maps and websites and verifies them in the same run: Google Maps Email Scraper and Website Contact & Email Finder.
License
MIT © Renzo Madueno
