Disclosure: we built and maintain the tool in this post (email-list-cleaner, MIT). This article was written with AI assistance and reviewed by us.
Bounces hurt sender reputation, and many "list verification" services require uploading your contacts to a third party. If you just need to catch the obvious problems, you can do it on your own machine with a zero-dependency Node.js CLI.
Repo: https://github.com/5012763083a-oss/email-list-cleaner
What it checks
- Syntax: is the address well-formed?
- MX lookup: does the domain publish mail servers? Public DNS only, with no SMTP probing, so no mail server is contacted.
- Disposable domains: flags throwaway inbox providers.
-
Role accounts: flags
info@,admin@,support@and similar addresses. -
Typos: suggests fixes like
gmial.com→gmail.com. - Duplicates: removed case-insensitively.
Nothing in your list leaves your machine. The only network traffic is DNS lookups for the domains.
Usage
Run it straight from GitHub with npx (Node required):
npx github:5012763083a-oss/email-list-cleaner contacts.csv -o cleaned.csv
Options:
--column email # which CSV column holds the address
--no-mx # skip DNS lookups (fully offline)
--no-dedupe # keep duplicates
For example, if your export has the address in a Email Address column and you're offline:
npx github:5012763083a-oss/email-list-cleaner export.csv --column "Email Address" --no-mx -o cleaned.csv
Reading the output
Your original columns are kept, and these are appended:
normalized,status,reason,syntaxValid,domain,hasMx,mxHosts,isDisposable,isRoleAccount,isFreeProvider,didYouMean
status is one of valid, invalid, risky or unknown. A practical workflow:
- Drop
invalidrows (bad syntax or no MX). - Review
riskyrows: disposable or role addresses may be fine for a B2B list but not for a newsletter. - Check
didYouMean: fixingjane@gmial.comrecovers a real subscriber instead of losing them. -
unknownusually means a DNS lookup failed; rerun later. It's also the status you get for every address with--no-mx, with the reasonmx_not_checked.
Open cleaned.csv in a spreadsheet and filter by status.
Limits
MX checks tell you a domain can receive mail, not that a specific mailbox exists. That's deliberate: confirming mailboxes requires SMTP probing, which is slow and can get your IP flagged. For most list hygiene, syntax + MX + disposable + typo checks catch the bulk of bad addresses.
The free edition processes the first 500 rows per file. It's MIT-licensed, so you can fork it and change FREE_LIMIT in bin/email-clean.js.
Run the tests with npm test.
If you'd rather support the project, Email List Cleaner Pro ($9) removes the cap and adds batch mode and a summary report: https://6907000850732.gumroad.com/l/khnxbj?ref=devto
Top comments (0)