Skip to content

Repository files navigation

StackVerify Logo

@stackverify/email-check

High-performance email validation library for Node.js and the browser.

Validate syntax, detect disposable emails, verify DNS/MX records, and score inbox delivery likelihood — zero dependencies, fully tree-shakeable.

npm versionbundle sizelicenseTypeScriptNode.js

Installation · Quick Start · API · Tree-Shaking · Contributing


Why email-check?

Validating email addresses goes far beyond regex. @stackverify/email-check gives you a fast, lightweight, multi-layer validation pipeline that catches invalid syntax, blocks disposable throwaway addresses, verifies the domain can actually receive mail, and estimates whether the message will land in the inbox or the spam folder.

CapabilityWhat it doesBrowserNode.js
Syntax validationRegex-based RFC-light syntax check
Disposable detectionFlags 5,100+ known throwaway domains
Domain existenceDNS A/AAAA record lookup
MX record checkVerifies the domain can receive email
Inbox scoringRates delivery likelihood (low / medium / high)
  • Zero dependencies — nothing to install, nothing to audit.
  • Dual-format — ships ESM and CommonJS out of the box.
  • Fully typed — first-class TypeScript declarations.
  • Tree-shakeable — import only what you need via sub-path exports.
  • 312 KB dist total — the disposable domain database compresses to ~27 KB gzipped.

Installation

npm install @stackverify/email-check
yarn add @stackverify/email-check
pnpm add @stackverify/email-check

Quick Start

Full Validation (Node.js)

import{checkEmail}from"@stackverify/email-check";constresult=awaitcheckEmail("user@gmail.com");if(!result.isValid){console.error(`Rejected: ${result.reason}`);}else{console.log(`Accepted — inbox score: ${result.inbox.score} (${result.inbox.label})`);}

Browser-Only (Syntax + Disposable)

import{checkEmail}from"@stackverify/email-check";// In the browser, DNS checks are skipped automatically.constresult=awaitcheckEmail("user@example.com");console.log(result.syntax);// trueconsole.log(result.disposable);// false

CommonJS

const{ checkEmail }=require("@stackverify/email-check");checkEmail("user@example.com").then((result)=>{if(!result.isValid){console.log(`Invalid: ${result.reason}`);}});

API Reference

checkEmail(email: string): Promise<EmailCheckResult>

Runs the full validation pipeline. Returns a result object.

Result Object

PropertyTypeDescription
isValidbooleantrue if the email passed every applicable check.
syntaxbooleantrue if the email matches a valid syntax pattern.
disposablebooleantrue if the domain is a known disposable / throwaway provider.
domainExistsbooleantrue if the domain resolves via DNS. false in browsers.
hasMXbooleantrue if the domain has MX records. false in browsers.
inbox{ score: number; label: "low" | "medium" | "high" }Delivery likelihood estimate.
reasonstring | nullHuman-readable reason the email was rejected, or null if valid.

Possible reason values

reasonMeaning
"Invalid email syntax"The address does not match a valid email format.
"Disposable email provider"The domain is a known temporary / throwaway service.
"Domain does not exist"DNS lookup failed — the domain is not registered.
"Domain cannot receive email"The domain has no MX records.
nullThe email passed all checks.

Sub-Path Imports

Import only the pieces you need — bundlers will tree-shake the rest.

// Just syntax validation (111 bytes gzipped)import{isValidSyntax}from"@stackverify/email-check/syntax";// Just disposable detection (281 bytes gzipped + data)import{isDisposable}from"@stackverify/email-check/disposable";// Just inbox scoring (241 bytes gzipped)import{inboxScore}from"@stackverify/email-check/inbox-score";

isValidSyntax(email: string): boolean

Synchronous syntax check. Returns true if the email matches /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.

isDisposable(domain: string): boolean

Synchronous check against a database of 5,100+ known disposable email domains. Supports subdomain matching (e.g. sub.mailinator.com is flagged).

inboxScore(domain: string): { score: number; label: "low" | "medium" | "high" }

Returns a delivery likelihood score. Trusted providers (Gmail, Outlook, Yahoo, iCloud, Proton, Zoho) receive a score of 95 ("high"). All other valid domains receive 70 ("medium").


Tree-Shaking & Bundle Size

The library is designed for minimal bundle impact. If you only need one capability, import the sub-path directly:

// Your bundler (webpack, Vite, esbuild, Rollup) will only include what you import.import{isValidSyntax}from"@stackverify/email-check/syntax";
ImportRawGzipped
@stackverify/email-check (full)1.5 KB527 B
@stackverify/email-check/syntax97 B111 B
@stackverify/email-check/disposable584 B281 B
@stackverify/email-check/inbox-score402 B241 B
Disposable domain data70 KB27 KB

The disposable domain database is the primary payload. If you do not need disposable detection, avoid importing it and your total cost is under 1 KB gzipped.


Validation Pipeline

checkEmail() runs checks in order and returns early on the first failure:

Email input
│
▼
Syntax check ──────── fail → "Invalid email syntax"
│
▼
Domain extraction ─── fail → "Invalid email domain"
│
▼
Disposable check ──── fail → "Disposable email provider"
│
▼
Domain exists ─────── fail → "Domain does not exist" (Node.js only)
│
▼
MX record check ───── fail → "Domain cannot receive email" (Node.js only)
│
▼
Inbox scoring
│
▼
isValid = true

Bulk Validation

import{checkEmail}from"@stackverify/email-check";constemails=["real.user@gmail.com","throwaway@tempmail.com"," typo@broken-domain ","nobody@doesnotexist12345.xyz",];for(constemailofemails){constresult=awaitcheckEmail(email);if(!result.isValid){console.log(`SKIP ${email}${result.reason}`);}elseif(result.inbox.label==="low"){console.log(`WARN ${email} — low inbox score`);}else{console.log(`OK ${email} — score ${result.inbox.score}`);}}

Trusted Providers

The following email providers are classified as high trust (inbox score 95):

ProviderDomain(s)
Gmailgmail.com, googlemail.com
Microsoftoutlook.com, hotmail.com
Yahooyahoo.com
Appleicloud.com
Protonproton.me, protonmail.com
Zohozoho.com
StackVerifystackverify.site

All other valid domains receive a score of 70 ("medium").


Node.js vs Browser

FeatureNode.jsBrowser
Syntax validation
Disposable detection
Domain existence (DNS)❌ Skipped
MX record check❌ Skipped
Inbox scoring

The library auto-detects the runtime. DNS-based checks are only performed in Node.js — in the browser they are silently skipped, so domainExists and hasMX remain false.


Use Cases

  • SaaS signup forms — block disposable emails at registration.
  • Marketing platforms — verify list quality before sending campaigns.
  • Fraud prevention — flag suspicious or temporary email addresses.
  • Lead generation — score and prioritize contacts by email quality.
  • Authentication flows — validate emails during signup or password reset.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.


License

MIT — free for personal, commercial, and SaaS use.


Author

Morgan Miller · StackVerify

Built and maintained by the StackVerify team as part of our marketing and SaaS toolkit.

About

A fast and reliable email validation library by Morgan Miller / StackVerify. Detects disposable emails, verifies domain and MX records, and provides inbox delivery likelihood. Designed for Node.js, TypeScript, ESM, and JavaScript projects.

Topics

Resources

Contributing

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages