Skip to content

CLI and tools

CLI

Run the free open-source DNSMigrator CLI to check, translate, lint, diff, export, and inspect DNS zones without storing or accepting provider credentials.

4 min read

On this page

The free, open-source DNS migration CLI dnsmigrator checks public DNS and translates, lints, diffs, or exports BIND zone files without provider credentials. It shares the core parser and translation engine with the web app, but it cannot read private provider APIs or apply a migration.

How to run the DNS migration CLI#

The package requires Node.js 20 or newer. Run the current published command without a global install:

bash
npx dnsmigrator --help

Start with a public domain check:

bash
npx dnsmigrator check example.com --to cloudflare

Or inspect a local zone file:

bash
npx dnsmigrator lint example.com.zone --provider cloudflare --strict
npx dnsmigrator translate example.com.zone --to cloudflare --out cloudflare.zone

The executable name inside scripts is dnsmigrator. When you invoke it through npx, place all command arguments after the package name as shown above.

Commands at a glance#

CommandPurposeNetwork access
checkDetect DNS host and registrar, inspect DNSSEC, discover public records, and compare destinationsPublic DNS and RDAP
translateConvert a BIND zone for one destination providerNone
diffCompare two BIND files by record setNone
lintFind parse, DNS consistency, TTL and provider-capability problemsNone
exportNormalize to BIND, emit canonical JSON, or generate dnsconfig.jsNone
propagationCompare one record across the configured public resolver setPublic DNS
dnssecCompare parent DS and child DNSKEY data and test validationPublic DNS
providersList catalog capabilities or inspect one providerNone

Use the full command reference for every positional argument, flag, JSON shape, strict-mode condition and example.

Global options#

Global options can appear before or after the command.

OptionBehavior
--jsonWrites one machine-readable JSON value to stdout. Errors become { "error": { "type", "message" } }.
--no-colorDisables ANSI colors. The CLI also honors a non-empty NO_COLOR environment variable.
--strictChanges a successful inspection into exit code 1 when that command’s documented findings condition is true.
-h, --helpShows main or command help without running the operation. dnsmigrator help <command> is also accepted.
-v, --versionPrints the package version. With --json, prints { "version": "…" }.

Unknown commands, options and extra positional arguments are rejected rather than ignored. Provider arguments accept a catalog ID, provider slug, display name, or DNSControl provider ID. Close misspellings may include a suggestion.

Exit codes#

CodeMeaning
0Command completed; either no strict findings exist or --strict was not requested.
1--strict was requested and the command found the condition documented for that command.
2Usage error, including a bad option, missing argument, invalid domain, invalid provider, or mismatched zones.
3Runtime error, such as a missing file, permission error, failed DNS query, or unexpected exception.

--strict is useful in CI because ordinary human-readable commands still return 0 when they successfully report a warning or diff. For example:

bash
npx dnsmigrator diff committed.zone generated.zone --strict
case $? in
  0) echo "zones match" ;;
  1) echo "zone drift found" ;;
  2) echo "command usage is invalid" ;;
  3) echo "comparison could not run" ;;
esac

Zone-file input#

File commands use the BIND parser documented under BIND zone files. Include $ORIGIN in the file or pass --origin example.com. translate explicitly supports - as the zone-file path for stdin.

bash
cat example.com.zone | npx dnsmigrator translate - --to route53 > route53.zone

Input is bounded by the core zone-file limit. The parser can return both usable records and line-specific errors; command behavior differs by operation. lint reports parse failures as findings, while commands that need at least one record return a runtime error if nothing can be parsed. With --strict, translate, lint, and export fail on partial parse errors; diff --strict is based on record-set differences, though its JSON still reports parse errors.

JSON automation#

Every command accepts --json, but each command returns its native result shape rather than a single generic envelope. This keeps record data structured. A usage failure has a stable error envelope:

json
{
  "error": {
    "type": "usage",
    "message": "Missing required option --to."
  }
}

Runtime failures use "type": "runtime". On JSON failures, stderr stays empty. Do not parse the human tables; select fields from JSON instead:

bash
npx dnsmigrator providers --json | jq -r '.[].id'
npx dnsmigrator diff before.zone after.zone --json | jq '.summary'
npx dnsmigrator lint zone.db --json | jq '.findings[] | select(.severity == "error")'

Credentials and privacy#

The CLI has no credential flags and never asks for API tokens, cloud keys or registrar passwords. translate, lint, diff, export, and providers operate on local input and the bundled provider catalog. check, dnssec, and propagation query public DNS; check also uses public RDAP data and can only discover records visible through DNS.

Public discovery is not a provider backup. Unless an authoritative server permits AXFR, the checker probes known names and may return only part of a zone. Connect the provider in the web app or use an exported zone file for a complete migration preview.

When to switch to the web app#

Use the web app when you need provider API reads, encrypted connections, a destination snapshot, a reviewed apply, authoritative verification, rollback, bulk migration, or nameserver cutover. Follow Quickstart: your first migration, or use the free web tools when a browser workflow is more convenient.