Mailcheck
A lightweight JavaScript library that suggests the right domain when users misspell their email address in a form.
Repository Health
Technical Analysis
Mailcheck is a small, dependency-free JavaScript library (with an optional jQuery plugin wrapper) that catches typos in email addresses as users type them into a form. When someone enters “user@gmial.con”, Mailcheck suggests “user@gmail.com” using a string-distance algorithm (Sift3/Sift4) run against a configurable list of common domains, second-level domains, and top-level domains.
It runs entirely client-side with no network calls, ships as a single file, and works with or without jQuery, in the browser, via AMD, or in Node/CommonJS. Companies like Dropbox, Kickstarter, Lyft, and Khan Academy have used it to reduce bounced signup and welcome emails caused by simple typos.
What You Get
- A pure
Mailcheck.run()API that takes an email and returns a suggested correction object (address,domain,full) or nothing if the address looks fine - An optional jQuery plugin (
$(el).mailcheck()) that wraps the core API for drop-in use on any input field - Configurable domain lists (
domains,secondLevelDomains,topLevelDomains) so suggestions match your actual user base instead of a generic default set - A built-in Sift3/Sift4 string-distance function, with the option to swap in your own distance algorithm
- Zero runtime dependencies and a minified build (
mailcheck.min.js) small enough to inline in a signup page
Common Use Cases
- Catching a mistyped domain (
gmial.com,hotnail.com) on a signup, checkout, or newsletter form before submission - Reducing bounced transactional and welcome emails caused by simple keystroke errors
- Adding an inline “Did you mean gmail.com?” suggestion UI next to an email input field
- Validating internal or B2B signup forms against a custom, restricted list of company email domains
Under The Hood
Architecture Mailcheck is a single flat object literal (Mailcheck, defined in src/mailcheck.js) with no classes, no build step, and no internal module boundaries. run() is the entry point: it fills in default domain lists and a default distance function, splits the candidate email via splitEmail() into address/second-level-domain/top-level-domain parts, and hands off to suggest(), which runs findClosestDomain() three times (full domain, second-level, top-level) against the configured lists and stitches together a corrected domain if any part scores within threshold. The optional jQuery plugin at the bottom of the same file ($.fn.mailcheck) is a thin adapter that reads this.val() and forwards to Mailcheck.run, wrapping the suggested/empty callbacks to also receive the target element — the whole library is one file with three export paths (CommonJS module.exports, AMD define, and a global window.jQuery hook).
Tech Stack Plain ES5 JavaScript with zero runtime dependencies (package.json dependencies: {}); the only external dependency, jQuery, is optional and detected at runtime via typeof window !== 'undefined' && window.jQuery. Build/dev tooling is Grunt-based (Gruntfile.coffee, written in CoffeeScript) driving grunt-contrib-jshint for linting and grunt-contrib-uglify for producing the committed src/mailcheck.min.js; tests run via grunt-jasmine-node/Jasmine. There is no TypeScript, no bundler config, and no package manager lockfile beyond the legacy bower.json, reflecting the library’s 2012-era origins as a plain script-tag/CommonJS distributable.
Code Quality spec/mailcheckSpec.js is a 345-line Jasmine suite covering run, suggest, findClosestDomain, splitEmail, and encodeEmail with both positive and negative cases (valid emails, malformed addresses, custom domain lists, custom distance functions). The core sift4Distance implementation is dense and effectively uncommented beyond a source-attribution link, making it the hardest part of the file to follow; the rest of the code uses descriptive names (emailParts, closestSecondLevelDomain) and short, single-purpose functions. There are no TypeScript types, no JSDoc annotations, and error handling is implicit (functions return false rather than throwing on malformed input) rather than validated with guard clauses or explicit exceptions.
API Design The public surface is intentionally minimal: one function (Mailcheck.run(opts)) taking a plain options object and two callbacks (suggested, empty), plus the jQuery convenience wrapper for teams that want zero boilerplate. Defaults for all three domain lists mean a consumer can get a working suggestion with just { email, suggested, empty }, while power users can override every list and swap the distance function. The trade-off is a slightly unusual dual-callback style (rather than a single return value or Promise) and mutation of the passed-in opts object inside run(), both of which are dated but well-documented in the README with copy-pasteable examples for jQuery, vanilla JS, and Node.