npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@chaisser/email-validator

v1.0.1

Published

Email validation with regex, syntax check, MX verification, and disposable domain detection

Readme

@chaisser/email-validator

Email validation with regex, syntax check, MX verification, and disposable domain detection

Comprehensive email validation covering syntax, RFC 5322 regex, DNS MX record lookups, SMTP mailbox verification, disposable/temp email detection, and common domain typo suggestions. Zero external dependencies.


Installation

npm install @chaisser/email-validator
# or
yarn add @chaisser/email-validator
# or
pnpm add @chaisser/email-validator

Quick Start

import {
  isValid,
  validate,
  isDisposable,
  hasTypo,
  suggestCorrection,
  checkSMTP,
  validateDetailed
} from '@chaisser/email-validator';

// Basic check
isValid('[email protected]'); // true

// Detailed reason
validate('[email protected]');
// { valid: false, reason: 'Domain starts with dot' }

// Disposable email check
isDisposable('[email protected]'); // true

// Typo detection
hasTypo('[email protected]');           // true
suggestCorrection('[email protected]'); // '[email protected]'

// SMTP mailbox verification (checks if inbox really exists)
const result = await checkSMTP('[email protected]');
// { reachable: true, mailboxExists: true/false/null, response: '...', mxHost: 'gmail-smtp-in.l.google.com' }

// Full validation
const detailed = await validateDetailed('[email protected]', { checkMX: true });
// { valid, syntax, regex, mx, disposable, typo, normalized, domain, localPart, reasons }

API Reference

Basic Validation

| Function | Returns | Description | |----------|---------|-------------| | isValid(email) | boolean | Quick format check | | validate(email) | { valid, reason? } | Validate with failure reason | | isValidRegex(email) | boolean | RFC 5322 regex check | | isValidStrict(email) | boolean | Strict allowed chars check | | isValidLength(email) | boolean | Max 254 chars | | isValidLocalPart(email) | boolean | Local part max 64 chars | | isValidDomain(email) | boolean | Domain format check |

Normalize

| Function | Description | |----------|-------------| | normalize(email) | Trim + lowercase | | normalizeGmail(email) | Remove dots and +tags for Gmail addresses |

Parse

| Function | Returns | |----------|---------| | parse(email) | { localPart, domain, tld } or null | | getDomain(email) | Domain string | | getTLD(email) | TLD string | | getLocalPart(email) | Local part string |

Disposable Detection

| Function | Description | |----------|-------------| | isDisposable(email) | Check if email uses disposable domain | | isDisposableDomain(domain) | Check domain directly | | getDisposableDomains() | Get all known disposable domains | | addDisposableDomain(domain) | Add a domain to the list | | removeDisposableDomain(domain) | Remove a domain from the list |

Typo Detection

| Function | Description | |----------|-------------| | hasTypo(email) | Check if domain looks like a typo | | suggestCorrection(email) | Suggest corrected email or null | | getSuggestions(domain) | Get matching correct domains |

Detects typos for: gmail.com, yahoo.com, hotmail.com, outlook.com, live.com, icloud.com, protonmail.com, aol.com, mail.com, zoho.com, yandex.com, qq.com, and more.

Classification

| Function | Description | |----------|-------------| | isFreeProvider(email) | Gmail, Yahoo, Outlook, etc. | | isBusinessEmail(email) | Not free provider, not disposable |

MX Records (DNS)

| Function | Description | |----------|-------------| | hasMXRecords(domain) | Check if domain has MX records | | getMXRecords(domain) | Get sorted list of MX hosts | | getMXRecordsWithPriority(domain) | Get MX records with priority values |

All async. Uses Node.js built-in dns module.

SMTP Mailbox Verification

| Function | Description | |----------|-------------| | checkSMTP(email, options?) | Connect to MX server and verify mailbox exists |

Options: { timeout?: number, from?: string } (default timeout 10s)

Returns { reachable, mailboxExists, response, mxHost }:

  • reachable: Server was reachable
  • mailboxExists: true / false / null (null = couldn't determine)

Full Validation

| Function | Description | |----------|-------------| | validateDetailed(email, options?) | Complete validation with all checks |

Options: { checkMX?: boolean, checkSMTP?: boolean, smtpTimeout?: number }

Returns:

{
  valid, syntax, regex, mx, disposable, typo,
  normalized, domain, localPart, reasons[]
}

Examples

Signup Form Validation

import { validate, isDisposable, hasTypo, suggestCorrection } from '@chaisser/email-validator';

function validateSignupEmail(email: string) {
  const { valid, reason } = validate(email);
  if (!valid) return { error: reason };

  if (isDisposable(email)) return { error: 'Disposable emails not allowed' };

  if (hasTypo(email)) {
    return { warning: `Did you mean ${suggestCorrection(email)}?` };
  }

  return { valid: true, email };
}

Verify Email Exists Before Sending

import { validateDetailed } from '@chaisser/email-validator';

async function verifyBeforeSend(email: string) {
  const result = await validateDetailed(email, { checkMX: true, checkSMTP: true });

  if (!result.valid) return { canSend: false, reasons: result.reasons };
  if (result.mx === false) return { canSend: false, reasons: ['Domain has no mail server'] };
  if (result.disposable) return { canSend: false, reasons: ['Disposable email'] };

  return { canSend: true };
}

Normalize Gmail Addresses

import { normalizeGmail } from '@chaisser/email-validator';

// All these resolve to the same normalized address
normalizeGmail('[email protected]');       // '[email protected]'
normalizeGmail('[email protected]'); // '[email protected]'
normalizeGmail('[email protected]');  // '[email protected]'

Bulk MX Check

import { getMXRecords } from '@chaisser/email-validator';

const domains = ['gmail.com', 'company.com', 'fake-domain.invalid'];

for (const domain of domains) {
  const mx = await getMXRecords(domain);
  console.log(`${domain}: ${mx.length > 0 ? mx.join(', ') : 'NO MX RECORDS'}`);
}

License

MIT