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:
npx dnsmigrator --helpStart with a public domain check:
npx dnsmigrator check example.com --to cloudflareOr inspect a local zone file:
npx dnsmigrator lint example.com.zone --provider cloudflare --strict
npx dnsmigrator translate example.com.zone --to cloudflare --out cloudflare.zoneThe 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#
| Command | Purpose | Network access |
|---|---|---|
check | Detect DNS host and registrar, inspect DNSSEC, discover public records, and compare destinations | Public DNS and RDAP |
translate | Convert a BIND zone for one destination provider | None |
diff | Compare two BIND files by record set | None |
lint | Find parse, DNS consistency, TTL and provider-capability problems | None |
export | Normalize to BIND, emit canonical JSON, or generate dnsconfig.js | None |
propagation | Compare one record across the configured public resolver set | Public DNS |
dnssec | Compare parent DS and child DNSKEY data and test validation | Public DNS |
providers | List catalog capabilities or inspect one provider | None |
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.
| Option | Behavior |
|---|---|
--json | Writes one machine-readable JSON value to stdout. Errors become { "error": { "type", "message" } }. |
--no-color | Disables ANSI colors. The CLI also honors a non-empty NO_COLOR environment variable. |
--strict | Changes a successful inspection into exit code 1 when that command’s documented findings condition is true. |
-h, --help | Shows main or command help without running the operation. dnsmigrator help <command> is also accepted. |
-v, --version | Prints 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#
| Code | Meaning |
|---|---|
| 0 | Command 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. |
| 2 | Usage error, including a bad option, missing argument, invalid domain, invalid provider, or mismatched zones. |
| 3 | Runtime 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:
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" ;;
esacZone-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.
cat example.com.zone | npx dnsmigrator translate - --to route53 > route53.zoneInput 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:
{
"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:
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.