A robust email validation library that goes beyond basic regex validation by checking:
- DNS MX records to verify domain existence
- Provider-specific rules for usernames (e.g., Gmail, Yahoo)
- Common domain typos (e.g., "gmial.com" instead of "gmail.com")
- Custom domain blocklists
Most email validators only check basic syntax, allowing many invalid emails to pass. This library catches emails that other validators miss:
Invalid Email | Reason |
---|---|
[email protected] | Gmail doesn't allow "_" and "-" symbols |
[email protected] | "8avymt4v93mvt3t03.com" isn't a real domain and doesn't have DNS MX records |
s!o#m$e%o^n&[email protected] | Most public email providers only allow "a-z","0-9",".","_","-","+" before "@" |
[email protected] | Common typo that can be blocked with the domain blocklist feature |
- Works in both Browser and Node.js environments
- Written in TypeScript with full type definitions
- Zero dependencies
- Customizable validation rules
- DNS-over-HTTPS (DoH) support for browser environments
- Custom MX resolver support for Node.js
- Domain blocklist support
- Detailed validation error reasons
# NPM
npm install email-validator-dns-provider-rules
# Yarn
yarn add email-validator-dns-provider-rules
# pnpm
pnpm add email-validator-dns-provider-rules
import {validateEmail} from "email-validator-dns-provider-rules";
// Basic validation
const result = await validateEmail('[email protected]');
if (!result.valid) {
console.log(`Email is invalid: ${result.reasonText}`);
}
Validates an email address using DNS checks and provider-specific rules.
Parameters:
email
(string): The email address to validateoptions
(object, optional): Configuration options
Returns:
- Promise: Object with validation results
ValidationResult Object:
valid
(boolean): Whether the email is validreasonId
(number, optional): ID of the validation failure reasonreasonText
(string, optional): Human-readable description of the validation failure
interface ValidatorOptions {
blocklistDomains?: string[]; // Domains to block
dohProviderUrl?: string; // Custom DNS-over-HTTPS provider URL
dohRetryAmount?: number; // Number of retries for DNS queries
skipCache?: boolean; // Skip the internal MX domain cache
mxResolver?: (domain: string) => Promise<string[] | false>; // Custom MX resolver
}
You can provide your own error messages by mapping the reason IDs:
const customReasons = {
[INVALID_REASON_AMOUNT_OF_AT]: 'Email must contain exactly one @ symbol',
[INVALID_REASON_USERNAME_GENERAL_RULES]: 'Username contains invalid characters',
[INVALID_REASON_DOMAIN_GENERAL_RULES]: 'Domain name is invalid',
[INVALID_REASON_NO_DNS_MX_RECORDS]: 'Domain does not have mail server records',
[INVALID_REASON_DOMAIN_IN_BLOCKLIST]: 'This email domain is not allowed',
[INVALID_REASON_USERNAME_VENDOR_RULES]: 'Username does not meet provider requirements',
[INVALID_REASON_DOMAIN_POPULAR_TYPO]: 'Domain appears to be a typo (did you mean gmail.com?)',
};
const result = await validateEmail('[email protected]');
if (!result.valid) {
console.log(`Email is invalid: ${customReasons[result.reasonId]}`);
}
You can block specific domains:
const blockedDomains = [
'disposable-email.com',
'temporary-mail.org',
'hotnail.com' // Common typo of hotmail.com
];
const result = await validateEmail('[email protected]', {
blocklistDomains: blockedDomains
});
// result.valid will be false
You can specify a custom DNS-over-HTTPS provider:
const result = await validateEmail('[email protected]', {
dohProviderUrl: 'https://your-custom-doh-provider.com/dns-query'
});
For Node.js environments, you can use the native DNS module:
import {resolveMx} from 'dns/promises';
async function nodeResolver(emailDomain: string): Promise<string[] | false> {
try {
const records = await resolveMx(emailDomain);
return records.map(rec => rec.exchange);
} catch (error) {
if (error.message.includes('ENOTFOUND')) {
return []; // Empty records treated as invalid
}
return false; // Other errors treated as "can't determine"
}
}
const result = await validateEmail('[email protected]', {
mxResolver: nodeResolver
});
This project is licensed under the MIT License - see the LICENSE file for details.