Skip to content

namewiz/domainstat

Repository files navigation

DomainStat

Build Test NPM License

DomainStat is a lightweight TypeScript/JavaScript library for checking whether domain names are unregistered (available to register). It queries several data sources in a "first good win" order – DNS (DoH), RDAP and finally WHOIS API – and returns a uniform result describing the domain's status.

Node-specific utilities (e.g., host DNS, ping, whois library) have been removed to ensure consistent behavior and simpler usage. The library runs with fetch-based adapters.

Features

  • Fast: probes DNS first and cancels slower checks once a definitive answer is found.
  • 🔁 Three tier lookup: DNS → RDAP → WHOIS library/API.
  • 🧩 Consistent: single implementation across environments using DoH + RDAP + WHOIS API.
  • ⚙️ Customisable: per‑TLD overrides, pluggable logging and adapter include/ exclude filters.
  • 📦 Batch helpers: check lists of domains with concurrency limits or stream results as they arrive.

Installation

npm install domainstat

Quick Start

import { check, checkBatch, checkBatchStream, checkSerial, checkParallel, type DomainStatus } from 'domainstat'; const res = await check('example.com'); // { domain: 'example.com', availability: 'registered', resolver: 'dns.doh', raw: {...} } // checkBatch resolves to an array when all lookups finish const batch: DomainStatus[] = await checkBatch(['example.com', 'openai.org']); // checkBatchStream streams the array items as they complete const streamed: DomainStatus[] = []; for await (const item of checkBatchStream(['foo.dev', 'bar.io'])) { streamed.push(item); } // Run all adapters in parallel using burst mode const fast = await check('example.com', { burstMode: true });

Both batch helpers produce arrays of DomainStatus; checkBatch waits for all results, while checkBatchStream yields items as they become available.

The availability field can be unregistered, registered, unsupported, invalid or unknown. The resolver indicates which adapter produced the result and raw contains the raw responses from each adapter.

Response Schema

Field Type Description
domain string Domain that was checked.
availability 'unregistered' | 'registered' | 'unsupported' | 'invalid' | 'unknown' Overall status of the domain.
resolver string Adapter namespace that produced the final result.
raw Record<string, any> Raw responses keyed by adapter namespace.
error? { code: string; message: string; retryable: boolean } Optional error details if lookup failed.

API

check(domain, options?)

Checks a single domain and resolves to a DomainStatus object.

checkSerial(domain, options?)

Sequential version of check that invokes adapters one after another.

checkParallel(domain, options?)

Runs all adapters concurrently and aborts pending ones once a result is found.

checkBatch(domains, options?)

Checks multiple domains concurrently and resolves to an array of DomainStatus objects.

checkBatchStream(domains, options?)

Returns an async generator yielding DomainStatus for each domain as soon as it finishes.

Options

Option Type Description
logger? Pick<Console, 'info' | 'warn' | 'error'> Custom logger used when verbose is true.
verbose? boolean Enable logging output.
concurrency? number Maximum concurrent lookups for batch helpers.
only? string[] Run only adapters whose namespace starts with these prefixes.
skip? string[] Skip adapters whose namespace starts with these prefixes.
tldConfig? TldConfigEntry Per‑TLD overrides such as RDAP server.
cache? boolean Enable or disable caching (default true).
apiKeys? { domainr?: string; whoisfreaks?: string; whoisxml?: string } API keys for third‑party services.
burstMode? boolean When true, use checkParallel to query all adapters simultaneously.
allottedLatency? Partial<Record<AdapterSource, number>> Per‑adapter latency before launching the next in serial mode; defaults to 200ms per entry.
timeoutConfig? Partial<Record<AdapterSource, number>> Maximum execution time per adapter in milliseconds.

Logging is disabled unless verbose is set. Set cache: false to disable caching.

Adapters

Namespace Description
validator Validates domain syntax and supported TLDs.
dns.doh DNS-over-HTTPS lookup (Cloudflare).
rdap Generic RDAP query.
rdap.ng RDAP lookup for .ng domains.
altstatus.domainr Domain status via Domainr API.
altstatus.mono Domain status via Mono Domains API.
altstatus Fallback when status APIs fail.
whois.api WHOIS lookup via external APIs.

API Keys

When running in the browser or when a WHOIS lookup is required, the library can use paid APIs. Provide credentials via the apiKeys option:

check('example.com', { apiKeys: { domainr: 'DOMAINR_KEY', whoisfreaks: 'WHOISFREAKS_KEY', whoisxml: 'WHOISXML_KEY', }, });

The library does not read environment variables for credentials; all API keys must be supplied explicitly through apiKeys.

Command-line Usage

The package also provides a CLI so you can check domains directly from your terminal without writing code:

npx domainstat google.com newdomain.dev

Results stream to stdout as soon as each lookup finishes. When connected to a TTY you get colourised, human-friendly output:

Index Domain Status Resolver Details ----- ------ ------- -------- -------- 1/2 google.com registered dns.doh latency:dns.doh=76ms 2/2 newdomain.dev unregistered rdap latency:dns.doh=73ms, rdap=193ms 

For machine consumption use the JSON output mode:

npx domainstat --json --only validator example.invalidtld

Key options include:

  • --concurrency <n> – control how many domains are checked at once.
  • --burst / --serial – choose whether adapters run in parallel or sequentially.
  • --only / --skip – restrict or exclude adapter namespaces.
  • --domainr-key, --whoisfreaks-key, --whoisxml-key – provide API keys when needed.
  • --skip-rdap, --rdap-server <url> – tweak RDAP behaviour.
  • --timeout adapter=ms – abort specific adapters after the given time.
  • --allotted-latency adapter=ms – adjust serial launch delays.

The CLI reads API keys from the environment variables DOMAINSTAT_DOMAINR_KEY, DOMAINSTAT_WHOISFREAKS_KEY and DOMAINSTAT_WHOISXML_KEY when the corresponding flags are not supplied.

Why No Node Utils?

Node-based utilities (host resolver, ping, whois library) are intentionally not supported:

  1. They may not be installed or available on the OS.
  2. Behavior differs across operating systems and environments.
  3. Processes tend to linger due to open network handles, slowing exit times.
  4. The only util that can fully resolve status (whois) lacks coverage for many TLDs; growth favors RDAP instead.
  5. Removing Node utils guarantees consistent results between Node and the browser.

If you need the previous Node-util adapters, see the v1 branch.

Demo

A small demo application lives in the demo/ directory.

npm run build npm run demo

Open the printed URL in your browser to test domain lookups via the bundled library.

Testing

npm test

License

ISC

About

Fast domain status checker that combines RDAP, WHOIS, DOH, and 3P APIs, with streaming support

Topics

Resources

License

Stars

Watchers

Forks