Mailcheck suggests a likely email domain when someone makes a typo. It is a small JavaScript library with an optional jQuery plugin. Mailcheck originated at Kicksend.
sample@gmial.con → sample@gmail.com
sample@gmail → sample@gmail.com
Mailcheck is a typo suggester, not an email validator or a deliverability check. Show a suggestion; do not silently replace an address or block someone from continuing.
- The established JavaScript API remains available: the same methods, options, callbacks, return values, browser global, and jQuery plugin.
- Bundled TypeScript declarations require no separate
@types/mailcheckpackage. - Recognized modern domain endings such as
.ai,.io,.app, and.coare not rewritten merely because another ending is close. - Provider defaults include Proton, HEY, Fastmail, and Tuta.
- An exact, unambiguous configured domain with a missing ending can be completed:
sample@gmailcan suggestsample@gmail.com. - Equally close candidates produce no suggestion rather than depending on list order.
- Local-part case and repeated literal percent signs are preserved.
- Mailcheck has no runtime dependencies and makes no network requests.
npm install mailcheckLoad the browser build before calling Mailcheck.run:
<script src="/path/to/mailcheck.min.js"></script>Call Mailcheck.run() when the person leaves the email field. Render the suggestion as text, never as HTML.
<input id="email" type="email" autocomplete="email">
<p id="suggestion" aria-live="polite"></p>
<script src="/path/to/mailcheck.min.js"></script>
<script>
var email = document.getElementById('email');
var output = document.getElementById('suggestion');
email.addEventListener('blur', function () {
Mailcheck.run({
email: email.value,
suggested: function (suggestion) {
output.textContent = 'Did you mean ' + suggestion.full + '?';
},
empty: function () {
output.textContent = '';
}
});
});
</script>run() returns the suggestion when no callbacks are supplied:
var suggestion = Mailcheck.run({ email: 'sample@gmial.con' });
// { address: 'sample', domain: 'gmail.com', full: 'sample@gmail.com' }
// or undefined when there is no suggestionMailcheck does not alter the field value. Let the person choose whether to change it.
Load jQuery first, then Mailcheck:
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="/path/to/mailcheck.min.js"></script>$('#email').on('blur', function () {
$(this).mailcheck({
suggested: function (element, suggestion) {
$('#suggestion').text('Did you mean ' + suggestion.full + '?');
},
empty: function () {
$('#suggestion').empty();
}
});
});The plugin passes the jQuery element first and the suggestion second. It returns void.
var Mailcheck = require('mailcheck');
var suggestion = Mailcheck.run({ email: 'sample@gmial.con' });import Mailcheck from 'mailcheck';
import type { Suggestion } from 'mailcheck';
const suggestion: Suggestion | undefined = Mailcheck.run({
email: 'Sample.Name+Tag@gmial.com'
});The default import uses CommonJS interoperability, supported by Node ESM and TypeScript with esModuleInterop. For CommonJS TypeScript, use:
import Mailcheck = require('mailcheck');To use the existing jQuery plugin types alongside your normal jQuery types:
import type {} from 'mailcheck/jquery';This adds declarations only. Load the jQuery and Mailcheck runtime scripts as usual.
Pass lowercase lists to replace the relevant defaults:
Mailcheck.run({
email: 'sample@acme.con',
domains: ['acme.com', 'example.org'],
secondLevelDomains: ['acme'],
topLevelDomains: ['com', 'org']
});Or extend the defaults:
Mailcheck.defaultDomains.push('acme.com');
Mailcheck.defaultSecondLevelDomains.push('acme');
Mailcheck.defaultTopLevelDomains.push('org');domains, secondLevelDomains, and topLevelDomains replace their respective defaults when passed to run(). The public topLevelDomains list contains correction targets; Mailcheck’s internal recognition of real domain endings is not another option to configure.
You can provide a custom distance function:
Mailcheck.run({
email: 'sample@gmial.con',
distanceFunction: function (left, right) {
return Mailcheck.sift4Distance(left, right);
}
});Mailcheck deliberately abstains when confidence is low:
- Valid recognized endings remain unchanged.
sample@gmail.coreceives no suggestion because.cois real. - A missing ending is completed only from one exact full-domain target already in
domains. - Partial names, unknown domains, malformed layouts, Unicode/punycode domains, and ambiguous matches receive no suggestion.
- A threshold of
0means exact matches only. - Mailcheck does not prove that an address exists, accepts mail, or belongs to a person.
The lower-level Mailcheck.suggest() accepts explicit correction lists and returns a suggestion object or false:
Mailcheck.suggest(
'sample@gmial.con',
['gmail.com'],
['gmail'],
['com'],
Mailcheck.sift4Distance
);run() retains the legacy encodeEmail() behavior. That encoding is not a general HTML sanitizer. Use textContent, jQuery .text(), or your framework’s escaped text rendering when displaying suggestions. Do not insert user input with innerHTML.
Install the locked development dependencies without lifecycle scripts:
npm ci --ignore-scripts --no-audit --no-fund
npx --no-install playwright install chromium firefox webkit
npm run test:ciUseful commands:
| Command | Purpose |
|---|---|
npm run test:ci |
Run the full test suite. |
npm test |
Run core, regression, and release-packaging tests. |
npm run test:types |
Check TypeScript declarations. |
npm run test:package |
Test a packed archive as a separate consumer. |
npm run test:e2e |
Run browser tests in Chromium, Firefox, and WebKit. |
npm run build |
Regenerate src/mailcheck.min.js. |
npm run build:check |
Verify that the minified build is current. |
npm run test:release |
Test the local release archive workflow. |
When changing behavior, add a focused regression test and regenerate the minified build. The test suite uses synthetic addresses and local test resources only.
./cut_release.sh VERSION
./cut_release.sh VERSION --dry-runThe command writes Releases/mailcheck-VERSION.tgz and refuses to overwrite an existing archive. It creates the versioned metadata and minified build in a temporary copy, leaving checkout version files unchanged. The archive includes only runtime files, declarations, manifests, this README, and the license.
Organizations that have used Mailcheck include:
- Dropbox
- Hack Design
- Kicksend
- Kickstarter
- Khan Academy
- Lyft
- Minecraft
- SB Nation
- The Verge
- GOV.UK Pay
- Jo
- Derrick Ko — original author
- Wei Lu — maintainer
- Pradeep Elankumaran — maintainer (GitHub)
Mailcheck has also benefited from its wider contributor community; see the contributors page for the complete history.
- Preserve the public API and module entry points.
- Prefer no suggestion over a wrong one.
- Do not silently rewrite a person’s address.
- Keep new behavior covered in the relevant core, package, type, or browser tests.
- Run
npm run buildandnpm run test:cibefore proposing a change.
See README-1.x.md for the preserved pre-2.0 README and historical links.
MIT. See LICENSE.
