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 🙏

© 2025 – Pkg Stats / Ryan Hefner

yq-dns

v1.0.14

Published

A promise-based DNS resolver that aggregates multiple DNS-over-HTTPS (DoH) providers with concurrency control

Readme

yq-dns

npm version License: MIT TypeScript Node.js

A comprehensive, promise-based DNS resolver library that aggregates multiple DNS-over-HTTPS (DoH) providers with advanced concurrency control, email validation, and flexible configuration. Built with TypeScript for maximum type safety and developer experience.

📋 Table of Contents

🚀 Features

YQ-DNS is designed to be the most comprehensive and reliable DNS resolution library for modern JavaScript applications. It combines multiple DNS-over-HTTPS providers with intelligent load balancing, advanced error handling, and extensive email validation capabilities to deliver enterprise-grade DNS resolution with exceptional performance and reliability.

  • 🌐 Multiple DNS Providers: Google DoH, Cloudflare DoH, Quad9 DoH, and Node.js native DNS
  • ⚡ High Performance: Concurrent requests with intelligent load balancing
  • 🎯 Smart Provider Selection: Automatic failover and random selection
  • 🔧 Flexible Configuration: Per-provider concurrency and rate limiting
  • 📝 Full TypeScript Support: Complete type definitions and IntelliSense
  • 🌍 Cross-Platform: Works with Node.js 18+, Deno, and Bun
  • 📊 Complete DNS API: All standard DNS record types supported
  • 📧 Email Validation: Comprehensive email domain validation and webmail detection
  • 🛡️ Error Handling: Robust error handling with detailed error information
  • 🔄 Automatic Retry: Built-in retry logic with exponential backoff
  • 📈 Queue Management: Advanced queue management with rate limiter
  • 🎛️ Runtime Configuration: Dynamic configuration updates without restart

📦 Installation

YQ-DNS is available as an npm package and can be installed using any modern JavaScript package manager. The library is built with zero dependencies for maximum compatibility and minimal bundle size, making it perfect for both server-side applications and edge computing environments.

Using npm:

npm install yq-dns

Using Yarn:

yarn add yq-dns

Using pnpm:

pnpm add yq-dns

Requirements:

  • Node.js 18.0.0 or higher
  • TypeScript 4.5+ (for TypeScript projects)
  • Modern JavaScript environment with Promise support

🚀 Quick Start

Get started with YQ-DNS in seconds! The library offers two main approaches: standalone functions for simple DNS queries and the YqDns class for advanced configuration and control. Both approaches provide the same powerful DNS resolution capabilities with automatic provider selection and intelligent error handling.

Standalone Functions (Recommended for Simple Use Cases)

Standalone functions provide the quickest way to perform DNS lookups with sensible defaults and automatic provider selection:

// Using standalone functions (recommended for simple use cases)
import { resolve4, resolveMx, resolveAny } from 'yq-dns';

// Resolve A records
const addresses = await resolve4('example.com');
console.log(addresses); // ['93.184.216.34']

// Resolve MX records
const mxRecords = await resolveMx('example.com');
console.log(mxRecords); // [{ priority: 10, exchange: 'mail.example.com' }]

// Resolve with specific provider
const googleResult = await resolve4('example.com', undefined, 'google');

YqDns Class (For Advanced Configuration)

The YqDns class provides fine-grained control over DNS providers, concurrency limits, timeouts, and retry behavior:

// Using YqDns class (for advanced configuration)
import { YqDns } from 'yq-dns';

const dns = new YqDns({
  google: { enabled: true, limit: { concurrency: 10 } },
  cloudflare: { enabled: true, limit: { concurrency: 5 } }
});

const addresses = await dns.resolve4('example.com');

CommonJS Support

YQ-DNS fully supports CommonJS environments for maximum compatibility:

// CommonJS usage
const { resolve4, YqDns } = require('yq-dns');

const addresses = await resolve4('example.com');

🌐 DNS Providers

YQ-DNS integrates with multiple DNS providers to ensure maximum reliability, performance, and flexibility. Each provider offers unique advantages and can be configured independently with custom settings for concurrency, timeouts, and retry behavior. The library automatically selects the best available provider or allows manual provider specification for specific use cases.

Native Provider

The native provider leverages Node.js's built-in DNS resolution capabilities, providing seamless integration with system DNS settings and local network configurations.

  • Endpoint: Node.js built-in dns/promises module
  • Features: Supports all DNS methods including lookup()
  • Use Case: Local/internal DNS resolution, system DNS settings
  • Advantages: No external dependencies, respects system DNS configuration
  • Best For: Internal networks, development environments, system-integrated applications

Google DoH (DNS-over-HTTPS)

Google's public DNS service provides enterprise-grade DNS resolution with global infrastructure and comprehensive DNSSEC validation.

  • Endpoint: https://dns.google/resolve
  • Features: DNSSEC validation, high reliability, global anycast network
  • Use Case: Public DNS resolution with Google's infrastructure
  • Advantages: Global CDN, excellent uptime, DNSSEC support, comprehensive logging
  • Best For: Production applications, global services, DNSSEC-required environments

Cloudflare DoH (DNS-over-HTTPS)

Cloudflare's privacy-focused DNS service emphasizes user privacy with minimal logging and fast global resolution.

  • Endpoint: https://cloudflare-dns.com/dns-query
  • Features: Privacy-focused, minimal logging, malware protection
  • Use Case: Privacy-conscious applications, consumer-facing services
  • Advantages: Fast global network, strong privacy policy, built-in security features
  • Best For: Privacy-sensitive applications, consumer products, GDPR-compliant services

Quad9 DoH (DNS-over-HTTPS)

Quad9's security-focused DNS service provides threat intelligence and malware blocking while maintaining user privacy.

  • Endpoint: https://dns.quad9.net/dns-query
  • Features: Security-focused, threat blocking, privacy protection
  • Use Case: Security-sensitive applications, enterprise environments
  • Advantages: Malware blocking, threat intelligence, non-profit organization, no user tracking
  • Best For: Security-critical applications, enterprise networks, threat-aware environments

⚙️ Configuration

YQ-DNS provides extensive configuration options to fine-tune DNS resolution behavior according to your application's specific requirements. Each DNS provider can be configured independently with custom concurrency limits, rate limiting, timeouts, and retry policies. The configuration system supports both static initialization and dynamic runtime updates.

Basic Configuration Example

const dns = new YqDns({
  google: {
    enabled: true,
    limit: { concurrency: 10, rps: 100 },
    timeout: 5000,
    retries: 3
  },
  cloudflare: {
    enabled: true,
    limit: { concurrency: 5, rps: 50 }
  },
  quad9: { enabled: false },
  native: { enabled: true }
});

Configuration Options

  • enabled: Enable or disable the provider (boolean)
  • limit.concurrency: Maximum concurrent requests per provider (number)
  • limit.rps: Requests per second rate limit (number)
  • timeout: Request timeout in milliseconds (number)
  • retries: Number of retry attempts on failure (number)
  • priority: Provider selection priority (number, higher = preferred)

Dynamic Configuration Updates

// Update configuration at runtime
dns.setConfig('google', { enabled: false });
dns.setConfigs({ cloudflare: { limit: { concurrency: 15 } } });

📚 API Reference

The YQ-DNS API is designed for simplicity and flexibility, offering both class-based and functional approaches to DNS resolution. All methods return strongly-typed promises and support optional provider selection, custom timeouts, and advanced configuration options.

YqDns Class

The YqDns class provides a comprehensive DNS resolution interface with full configuration control and advanced features like provider management, concurrency control, and runtime configuration updates.

const dns = new YqDns(config?: YqConfig);

// Basic DNS resolution methods
dns.resolve4(hostname: string): Promise<string[]>          // IPv4 addresses
dns.resolve6(hostname: string): Promise<string[]>          // IPv6 addresses
dns.resolveMx(hostname: string): Promise<MxRecord[]>       // Mail exchange records
dns.resolveTxt(hostname: string): Promise<string[][]>      // Text records
dns.resolveCname(hostname: string): Promise<string[]>      // Canonical name records
dns.resolveNs(hostname: string): Promise<string[]>        // Name server records
dns.resolveSoa(hostname: string): Promise<SoaRecord>       // Start of Authority
dns.resolvePtr(ip: string): Promise<string[]>             // Reverse DNS lookup
dns.resolveSrv(hostname: string): Promise<SrvRecord[]>     // Service records
dns.resolveAny(hostname: string): Promise<AnyRecord[]>     // All available records

// Configuration methods
dns.setConfig(provider: string, config: ProviderConfig): void
dns.setConfigs(configs: Partial<YqConfig>): void

// Email validation
dns.emailValidator: EmailValidator

Standalone Functions

Standalone functions provide a lightweight alternative for simple DNS queries without the need for class instantiation. These functions use sensible defaults and automatic provider selection.

import { resolve4, resolveMx, resolveAny } from 'yq-dns';

// Use directly without creating a class instance
const addresses = await resolve4('example.com');           // Quick IPv4 resolution
const mxRecords = await resolveMx('example.com');          // Mail server lookup
const anyRecords = await resolveAny('example.com');        // Comprehensive DNS query

// With optional provider specification
const googleResult = await resolve4('example.com', undefined, 'google');
const cloudflareResult = await resolveMx('example.com', undefined, 'cloudflare');

Method Parameters

Most DNS resolution methods accept the following parameters:

  • hostname/ip: The domain name or IP address to resolve (string)
  • options: Optional configuration object (varies by method)
  • provider: Optional provider name for specific provider usage (string)

Return Types

All methods return strongly-typed promises with comprehensive type definitions for maximum TypeScript compatibility and IntelliSense support.

Email Validation

The Email Validation system provides comprehensive email address validation, domain analysis, and provider detection. It combines syntax validation, DNS lookups, and an extensive database of email providers to deliver accurate validation results with detailed metadata about the email address and its hosting provider.

EmailValidator Class

The EmailValidator class is the core component for email validation operations. It provides intelligent email analysis by checking syntax, validating domains through DNS resolution, detecting email providers, and identifying role-based addresses. The validator supports both basic and deep validation modes to accommodate different use cases and performance requirements.

validate(email: string, deep?: boolean): Promise<EmailResponse>

Performs comprehensive email validation and analysis, returning detailed information about the email address including provider detection, webmail availability, and role-based email identification.

Parameters:

  • email: Email address to validate (string)
  • deep (optional): Enable deep validation with additional DNS lookups and extended checks (default: false)

Returns: EmailResponse object with one of the following structures:

Success Response Structure:

{
  success: true,
  data: {
    provider: string,     // Email provider name (e.g., "Gmail", "Outlook")
    email: string,        // Normalized email address
    isFree: boolean,      // Whether it's a free email provider domain
    role: boolean,        // Whether it's a role-based email (admin, support, etc.)
    webmail?: string      // Webmail URL if available
  }
}

Error Response Structure:

{
  success: false,
  type: 'Syntax' | 'Rejected' | 'Invalid' | 'Disposable' | 'Error',
  email: string,
  role: boolean,        // Whether it's a role-based email
  message?: string      // Detailed error message (only present for 'Error' type)
}

Basic Email Validation Examples

Simple Validation:

import { YqDns } from 'yq-dns';

const validator = YqDns.emailValidator;

// Basic email validation
const result = await validator.validate('[email protected]');
if (result.success) {
  console.log('✅ Valid email');
  console.log('Provider:', result.data.provider);     // "Gmail"
  console.log('Webmail:', result.data.webmail);       // "https://mail.google.com"
  console.log('Role email:', result.data.role);       // false
} else {
  console.log('❌ Invalid email:', result.type);
}

Deep Validation Mode:

// Enable deep validation for thorough analysis
const deepResult = await validator.validate('[email protected]', true);
if (deepResult.success) {
  console.log('Provider:', deepResult.data.provider);
  console.log('Is role-based:', deepResult.data.role);  // likely true for "admin"
}

Provider Detection Examples

Major Email Providers:

// Gmail detection
const gmailResult = await validator.validate('[email protected]');
console.log(gmailResult.data?.provider);  // "Gmail"

// Outlook detection
const outlookResult = await validator.validate('[email protected]');
console.log(outlookResult.data?.provider);  // "Outlook"

// Yahoo detection
const yahooResult = await validator.validate('[email protected]');
console.log(yahooResult.data?.provider);  // "Yahoo"

// Corporate email detection
const corpResult = await validator.validate('[email protected]');
console.log(corpResult.data?.provider);  // "Microsoft"

Role-Based Email Detection

Identifying Role-Based Addresses:

// Common role-based emails
const roleEmails = [
  '[email protected]',
  '[email protected]',
  '[email protected]',
  '[email protected]',
  '[email protected]'
];

for (const email of roleEmails) {
  const result = await validator.validate(email);
  if (result.success && result.data.role) {
    console.log(`${email} is a role-based email`);
  }
}

Webmail Detection and Access

Webmail URL Extraction:

// Get webmail URLs for popular providers
const webmailEmails = [
  '[email protected]',      // https://mail.google.com
  '[email protected]',    // https://outlook.live.com
  '[email protected]',      // https://mail.yahoo.com
  '[email protected]'      // https://www.icloud.com/mail
];

for (const email of webmailEmails) {
  const result = await validator.validate(email);
  if (result.success && result.data.webmail) {
    console.log(`${email} -> ${result.data.webmail}`);
  }
}

Batch Email Validation

Validating Multiple Emails:

async function validateEmailBatch(emails: string[]) {
  const results = await Promise.allSettled(
    emails.map(email => validator.validate(email))
  );
  
  return emails.map((email, index) => {
    const result = results[index];
    if (result.status === 'fulfilled' && result.value.success) {
      return {
        email,
        valid: true,
        provider: result.value.data.provider,
        role: result.value.data.role,
        webmail: result.value.data.webmail
      };
    } else {
      return {
        email,
        valid: false,
        error: result.status === 'fulfilled' ? result.value.type : 'validation_failed'
      };
    }
  });
}

// Usage example
const emailList = [
  '[email protected]',
  'invalid.email',
  '[email protected]',
  '[email protected]'
];

const batchResults = await validateEmailBatch(emailList);
console.log('Batch validation results:', batchResults);

Error Handling and Response Types

Comprehensive Error Handling:

async function handleEmailValidation(email: string) {
  try {
    const result = await validator.validate(email);
    
    if (result.success) {
      return {
        status: 'valid',
        data: result.data
      };
    } else {
      // Handle different error types
      switch (result.type) {
        case 'Syntax':
          return { status: 'syntax_error', message: 'Invalid email format' };
        case 'Invalid':
          return { status: 'invalid_domain', message: 'Domain does not exist' };
        case 'Rejected':
          return { status: 'rejected', message: 'Email rejected by provider' };
        case 'Disposable':
          return { status: 'disposable', message: 'Disposable email address' };
        case 'Error':
          return { status: 'validation_error', message: result.message };
        default:
          return { status: 'unknown_error', message: 'Validation failed' };
      }
    }
  } catch (error) {
    return {
      status: 'exception',
      message: error instanceof Error ? error.message : 'Unexpected error'
    };
  }
}

// Usage
const validationResult = await handleEmailValidation('[email protected]');
console.log(validationResult);

Advanced Use Cases

Email Domain Analysis:

async function analyzeEmailDomain(email: string) {
  const result = await validator.validate(email, true); // Deep validation
  
  if (result.success) {
    const domain = email.split('@')[1];
    return {
      email: result.data.email,
      domain,
      provider: result.data.provider,
      hasWebmail: !!result.data.webmail,
      webmailUrl: result.data.webmail,
      isRoleBased: result.data.role,
      isPersonal: ['Gmail', 'Yahoo', 'Outlook', 'iCloud'].includes(result.data.provider),
      isCorporate: !['Gmail', 'Yahoo', 'Outlook', 'iCloud'].includes(result.data.provider)
    };
  } else {
    return {
      email,
      valid: false,
      errorType: result.type,
      errorMessage: result.message
    };
  }
}

const analysis = await analyzeEmailDomain('[email protected]');
console.log('Email analysis:', analysis);

Additional EmailValidator Methods

The EmailValidator class provides several utility methods for email validation and manipulation:

isEmail(email: string): boolean

Performs advanced email format validation with structural constraints.

Validation Rules:

  • Maximum 35 characters for the local part
  • Maximum 3 hyphens in the local part
  • Maximum 3 dots in the local part
  • Maximum 3 dots in the domain part
  • Maximum 2 hyphens in the domain part
  • Maximum 55 total characters in the email address
  • Local part must be at least 2 characters
  • Domain part must be at least 5 characters

Example:

const validator = EmailValidator.create();

validator.isEmail("[email protected]");  // true
validator.isEmail("[email protected]");               // false (domain too short)
validator.isEmail("[email protected]");           // false
isFreeDomain(email_or_domain: string): boolean

Checks if an email address or domain belongs to a free email provider (Gmail, Yahoo, Outlook, etc.).

Example:

validator.isFreeDomain('[email protected]');     // true
validator.isFreeDomain('gmail.com');            // true
validator.isFreeDomain('[email protected]');     // false
isDisposable(email: string): boolean

Checks if an email address is from a known disposable/temporary email provider.

Example:

validator.isDisposable('[email protected]'); // true
validator.isDisposable('[email protected]');  // false
isJson(input: string): string[] | null

Validates if a string is a JSON array of valid email addresses.

Returns: Array of valid emails if successful, null otherwise.

Example:

validator.isJson('["[email protected]", "[email protected]"]');
// Returns: ["[email protected]", "[email protected]"]

validator.isJson('["foo", 1, null]');  // Returns: null
validator.isJson('not json');           // Returns: null
extractEmails(input: string[]): string[]

Extracts valid email addresses from various input formats including:

  • Plain email addresses
  • Comma-separated values
  • URL-encoded strings (automatically decoded)
  • JSON arrays

Example:

// Single email
validator.extractEmails(["[email protected]"]);
// Returns: ["[email protected]"]

// Comma-separated emails
validator.extractEmails(["[email protected],[email protected]"]);
// Returns: ["[email protected]", "[email protected]"]

// URL-encoded
validator.extractEmails(["user%40example.com,test%40domain.com"]);
// Returns: ["[email protected]", "[email protected]"]

// JSON array
validator.extractEmails(['["[email protected]", "[email protected]"]']);
// Returns: ["[email protected]", "[email protected]"]

// Mixed formats
validator.extractEmails([
  "[email protected]",
  "[email protected],[email protected]",
  '["[email protected]"]'
]);
// Returns: ["[email protected]", "[email protected]", "[email protected]", "[email protected]"]
getProviderWebmailUrl(provider: ProviderName): string | null
getProviderWebmailUrl(provider: ProviderName, domainOrEmail: string): string | null
getProviderWebmailUrl(domainOrEmail: string): string | null

Retrieves the webmail URL for a given email provider. Supports multiple overloaded signatures for flexibility.

Parameters:

  • provider - Provider name (e.g., "Gmail", "Outlook") or domain/email
  • domainOrEmail (optional) - Domain name or full email address

Returns: Webmail URL string if found, null otherwise.

Example:

// Using provider name
validator.getProviderWebmailUrl('Gmail');
// Returns: "https://mail.google.com"

// Using domain
validator.getProviderWebmailUrl('outlook.com');
// Returns: "https://outlook.live.com"

// Using email address
validator.getProviderWebmailUrl('[email protected]');
// Returns: "https://mail.yahoo.com"

// Using provider name with domain
validator.getProviderWebmailUrl('Gmail', 'google.com');
// Returns: "https://mail.google.com"

// Unknown provider
validator.getProviderWebmailUrl('unknown-provider.com');
// Returns: null

🗂️ DNS Record Types

YQ-DNS supports all standard DNS record types with comprehensive parsing and type-safe return values. Each record type is optimized for specific use cases, from basic domain resolution to advanced service discovery and email routing. The library automatically handles record parsing and provides structured data objects for easy consumption.

| Record Type | Description | Use Cases | Return Type | |-------------|-------------|-----------|-------------| | A | IPv4 address records | Web hosting, basic domain resolution | string[] | | AAAA | IPv6 address records | Modern networking, dual-stack configurations | string[] | | MX | Mail exchange records | Email routing, mail server discovery | MxRecord[] | | TXT | Text records | Domain verification, SPF, DKIM, configuration | string[][] | | CNAME | Canonical name records | Domain aliases, CDN configuration | string[] | | NS | Name server records | DNS delegation, authoritative servers | string[] | | SOA | Start of Authority | Zone information, DNS administration | SoaRecord | | SRV | Service records | Service discovery, load balancing | SrvRecord[] | | PTR | Pointer records (reverse DNS) | IP to domain mapping, security verification | string[] | | CAA | Certificate Authority Authorization | SSL certificate validation | CaaRecord[] | | NAPTR | Name Authority Pointer | Complex service resolution | NaptrRecord[] | | TLSA | Transport Layer Security Authentication | Certificate pinning, security | TlsaRecord[] | | ANY | All available records | Comprehensive domain analysis | AnyRecord[] |

Record Type Examples

// A records - IPv4 addresses
const ipv4 = await resolve4('example.com');
// Returns: ['93.184.216.34']

// MX records - Mail servers with priority
const mailServers = await resolveMx('example.com');
// Returns: [{ priority: 10, exchange: 'mail.example.com' }]

// TXT records - Text data (SPF, DKIM, etc.)
const txtRecords = await resolveTxt('example.com');
// Returns: [['v=spf1 include:_spf.example.com ~all']]

// SRV records - Service discovery
const services = await resolveSrv('_sip._tcp.example.com');
// Returns: [{ priority: 10, weight: 5, port: 5060, name: 'sip.example.com' }]

🔷 TypeScript Support

YQ-DNS is built with TypeScript from the ground up, providing comprehensive type definitions, full IntelliSense support, and compile-time type checking. The library exports all necessary types and interfaces, ensuring type safety across your entire DNS resolution workflow and eliminating runtime type errors.

Complete Type Safety

import { YqDns, MxRecord, SrvRecord, ProviderName } from 'yq-dns';

// Strongly typed results with full IntelliSense
const mxRecords: MxRecord[] = await resolveMx('example.com');
const srvRecords: SrvRecord[] = await resolveSrv('_sip._tcp.example.com');

// Type-safe provider names prevent typos
const provider: ProviderName = 'google';
const addresses = await resolve4('example.com', undefined, provider);

Available Type Exports

// Core types
import {
  YqDns,                    // Main DNS class
  ProviderName,             // 'google' | 'cloudflare' | 'quad9' | 'native'
  YqConfig,                 // Configuration interface
  ProviderConfig,           // Individual provider configuration
  
  // DNS record types
  MxRecord,                 // Mail exchange record
  SrvRecord,                // Service record
  SoaRecord,                // Start of Authority record
  CaaRecord,                // Certificate Authority Authorization
  NaptrRecord,              // Name Authority Pointer
  TlsaRecord,               // Transport Layer Security Authentication
  AnyRecord,                // Union of all record types
  
  // Email validation types
  EmailValidator,           // Email validation class
  EmailResponse,            // Validation response type
  EmailData,                // Successful validation data
  EmailError                // Validation error type
} from 'yq-dns';

Generic Type Support

// Generic functions with type inference
const resolveWithType = async <T>(hostname: string, type: string): Promise<T> => {
  // Type-safe resolution with custom return types
  return await dns.resolveAny(hostname) as T;
};

// Usage with automatic type inference
const mxRecords = await resolveWithType<MxRecord[]>('example.com', 'MX');

📄 License

MIT License - see the LICENSE file for details.


Made with ❤️ by Yuniq Solutions Tech

For more information, visit our GitHub repository or check out our documentation.