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

@mailtester/core

v1.1.2

Published

Modern, high-performance email validation with RFC 5322 compliance, typo detection, disposable email blocking, MX verification, and SMTP validation

Readme

@mailtester/core

Modern, high-performance email validation for Node.js

npm version npm downloads Build Status TypeScript License: MIT

A comprehensive email validation library with RFC 5322 compliance, typo detection, disposable email blocking, MX record verification, and SMTP validation.

📚 DocumentationInstallationQuick StartAPI ReferenceConfigurationLicense


Features

  • RFC 5322 Compliant — Full regex validation with strict and loose modes
  • Typo Detection — Suggests corrections for common domain typos (gmaill.com → gmail.com)
  • Disposable Email Blocking — Detects 40,000+ temporary email services
  • MX Record Validation — Verifies domain has valid mail servers
  • SMTP Verification — Checks if mailbox actually exists
  • Bulk Validation — Process thousands of emails concurrently
  • Rate Limiting — Built-in protection against API abuse
  • TypeScript First — Full type safety with strict mode
  • Zero Config — Sensible defaults, works out of the box
  • Lightweight — ~25KB gzipped, minimal dependencies

Requirements

  • Node.js 16.0.0 or higher
  • TypeScript 5.3+ (for TypeScript users)

Installation

# npm
npm install @mailtester/core

# yarn
yarn add @mailtester/core

# pnpm
pnpm add @mailtester/core

Quick Start

Basic Validation

import { validate } from '@mailtester/core';

const result = await validate('[email protected]');

console.log(result.valid);  // true
console.log(result.score);  // 85 (0-100 reputation score)

With Configuration

import { validate } from '@mailtester/core';

const result = await validate('[email protected]', {
  preset: 'balanced',  // Skip SMTP for faster validation
  earlyExit: true      // Stop on first failure
});

if (!result.valid) {
  console.log(`Invalid: ${result.reason}`);
  // e.g., "Invalid: disposable"
}

Bulk Validation

import { validateBulk } from '@mailtester/core';

const emails = [
  '[email protected]',
  '[email protected]',
  '[email protected]'
];

const result = await validateBulk(emails, {
  concurrency: 10,
  onProgress: (completed, total) => {
    console.log(`Progress: ${completed}/${total}`);
  }
});

console.log(`Valid: ${result.valid}/${result.total}`);
// Valid: 2/3

Custom Validator Instance

import { createValidator } from '@mailtester/core';

// Create a reusable validator with custom config
const validator = createValidator({
  validators: {
    regex: { enabled: true },
    typo: { enabled: true },
    disposable: { enabled: true },
    mx: { enabled: true },
    smtp: { enabled: false }  // Disable SMTP for speed
  },
  earlyExit: true
});

// Validate multiple emails with same config
const result1 = await validator.validate('[email protected]');
const result2 = await validator.validate('[email protected]');

API Reference

validate(email, options?)

Validates a single email address.

const result = await validate('[email protected]');

Parameters:

  • email (string) — Email address to validate
  • options (Config, optional) — Validation configuration

Returns: Promise<ValidationResult>

interface ValidationResult {
  valid: boolean;           // Overall validity
  email: string;            // Email that was validated
  score: number;            // Reputation score (0-100)
  reason?: string;          // Which validator failed (if invalid)
  validators: {             // Individual validator results
    regex?: ValidatorResult;
    typo?: ValidatorResult;
    disposable?: ValidatorResult;
    mx?: ValidatorResult;
    smtp?: ValidatorResult;
  };
  metadata?: {
    timestamp?: string;     // ISO 8601 timestamp
    duration?: number;      // Validation duration in ms
  };
}

validateBulk(emails, options?)

Validates multiple email addresses concurrently.

const result = await validateBulk(emails, {
  concurrency: 10,
  onProgress: (completed, total) => console.log(`${completed}/${total}`)
});

Parameters:

  • emails (string[]) — Array of email addresses
  • options (BulkValidationOptions, optional) — Bulk validation options

Options: | Option | Type | Default | Description | |--------|------|---------|-------------| | concurrency | number | 10 | Max concurrent validations | | continueOnError | boolean | true | Continue if individual validation fails | | onProgress | function | — | Progress callback (completed, total) => void | | config | Config | — | Validation config for all emails | | rateLimit | object | — | Rate limiting configuration |

Returns: Promise<BulkValidationResult>

interface BulkValidationResult {
  results: ValidationResult[];  // Individual results
  total: number;                // Total emails processed
  valid: number;                // Count of valid emails
  invalid: number;              // Count of invalid emails
  errors: number;               // Count of errors
  duration: number;             // Total duration in ms
}

createValidator(config?)

Creates a reusable validator instance with custom configuration.

const validator = createValidator({ preset: 'strict' });
const result = await validator.validate('[email protected]');

Parameters:

  • config (Config, optional) — Validator configuration

Returns: ValidatorInstance

interface ValidatorInstance {
  validate(email: string): Promise<ValidationResult>;
  getConfig(): MergedConfig;
}

Configuration

Presets

Three built-in presets for common use cases:

| Preset | Validators | Early Exit | Use Case | |--------|------------|------------|----------| | strict | All enabled | Yes | Maximum validation (default) | | balanced | SMTP disabled | No | Fast validation with good coverage | | permissive | Regex only | Yes | Quick format check |

// Use strict preset (default)
await validate('[email protected]', { preset: 'strict' });

// Use balanced preset (no SMTP)
await validate('[email protected]', { preset: 'balanced' });

// Use permissive preset (regex only)
await validate('[email protected]', { preset: 'permissive' });

Custom Configuration

await validate('[email protected]', {
  validators: {
    regex: { enabled: true },
    typo: { enabled: true },
    disposable: { enabled: true },
    mx: { enabled: true },
    smtp: { enabled: false }
  },
  earlyExit: true,   // Stop on first failure
  timeout: 30000     // 30 second timeout
});

Configuration Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | preset | string | — | Use preset config: 'strict', 'balanced', 'permissive' | | validators | object | — | Enable/disable individual validators | | earlyExit | boolean | true | Stop validation on first failure | | timeout | number | — | Overall timeout in milliseconds |

Validators

Regex Validator

Validates email format according to RFC 5322 standards.

// Enabled by default
{ regex: { enabled: true } }

Checks:

  • Valid email format (local@domain)
  • Proper character usage
  • Domain structure
  • Internationalized domain names (IDN)

Typo Validator

Detects common domain typos and suggests corrections.

// Enabled by default
{ typo: { enabled: true } }

Examples:

  • gmaill.com → suggests gmail.com
  • yahooo.com → suggests yahoo.com
  • hotmal.com → suggests hotmail.com

Disposable Validator

Blocks temporary/disposable email services.

// Enabled by default
{ disposable: { enabled: true } }

Blocks:

  • 40,000+ known disposable domains
  • Pattern-based detection
  • Temporary email services

MX Validator

Verifies domain has valid mail exchange servers.

// Enabled by default
{ mx: { enabled: true } }

Checks:

  • MX records exist
  • DNS resolution works
  • Fallback to A records

SMTP Validator

Verifies mailbox exists by connecting to mail server.

// Enabled by default (disable for speed)
{ smtp: { enabled: true } }

Checks:

  • SMTP connection
  • RCPT TO verification
  • Mailbox existence

Note: SMTP validation may be blocked by some mail servers or firewalls. Consider using balanced preset if you experience timeouts.

Rate Limiting

Built-in rate limiting for bulk validation:

await validateBulk(emails, {
  rateLimit: {
    global: {
      requests: 100,  // Max requests
      window: 60      // Per 60 seconds
    },
    perDomain: {
      requests: 10,   // Max per domain
      window: 60      // Per 60 seconds
    }
  }
});

Error Handling

import { validate, ValidationError } from '@mailtester/core';

try {
  const result = await validate('[email protected]');
  
  if (!result.valid) {
    console.log(`Invalid email: ${result.reason}`);
    
    // Check specific validator errors
    if (result.validators.disposable?.error) {
      console.log('Disposable email detected');
    }
  }
} catch (error) {
  if (error instanceof ValidationError) {
    console.log(`Validation error: ${error.code}`);
  }
}

TypeScript Support

Full TypeScript support with strict mode:

import type {
  ValidationResult,
  ValidatorResult,
  Config,
  BulkValidationOptions,
  BulkValidationResult
} from '@mailtester/core';

// All types are exported
const config: Config = {
  preset: 'strict',
  earlyExit: true
};

const result: ValidationResult = await validate('[email protected]', config);

Performance

  • Single validation: < 150ms (without SMTP)
  • Bulk 100 emails: < 5 seconds
  • Package size: ~25KB gzipped

Tips for Better Performance

  1. Disable SMTP for faster validation:

    await validate(email, { preset: 'balanced' });
  2. Use bulk validation for multiple emails:

    await validateBulk(emails, { concurrency: 20 });
  3. Enable early exit to stop on first failure:

    await validate(email, { earlyExit: true });

Examples

Express.js Integration

import express from 'express';
import { validate } from '@mailtester/core';

const app = express();
app.use(express.json());

app.post('/api/validate-email', async (req, res) => {
  const { email } = req.body;
  
  const result = await validate(email, { preset: 'balanced' });
  
  res.json({
    valid: result.valid,
    score: result.score,
    reason: result.reason
  });
});

User Registration

import { validate } from '@mailtester/core';

async function registerUser(email: string, password: string) {
  // Validate email first
  const validation = await validate(email, {
    validators: {
      regex: { enabled: true },
      typo: { enabled: true },
      disposable: { enabled: true },
      mx: { enabled: true },
      smtp: { enabled: false }  // Skip for speed
    }
  });
  
  if (!validation.valid) {
    throw new Error(`Invalid email: ${validation.reason}`);
  }
  
  // Check for typo suggestions
  if (validation.validators.typo?.details?.suggestion) {
    // Optionally warn user about potential typo
    console.log(`Did you mean: ${validation.validators.typo.details.suggestion}?`);
  }
  
  // Proceed with registration...
}

Email List Cleaning

import { validateBulk } from '@mailtester/core';

async function cleanEmailList(emails: string[]) {
  const result = await validateBulk(emails, {
    concurrency: 20,
    config: { preset: 'balanced' },
    onProgress: (completed, total) => {
      const percent = Math.round((completed / total) * 100);
      console.log(`Cleaning: ${percent}%`);
    }
  });
  
  const validEmails = result.results
    .filter(r => r.valid)
    .map(r => r.email);
  
  console.log(`Cleaned: ${validEmails.length}/${emails.length} valid`);
  
  return validEmails;
}

Contributing

Contributions are welcome! Please read our Contributing Guide for details.

# Clone the repository
git clone https://github.com/kazmiali/mailtester.git

# Install dependencies
yarn install

# Run tests
yarn test

# Build
yarn build

License

MIT © Ali Kazmi


Report BugRequest FeatureStar on GitHub