DomainKit defines a small, auditable public contract for DNS provisioning. Changes should keep provider APIs, host storage, and product UI outside the core protocol unless an accepted architecture decision says otherwise.
Use Bun 1.4 and Node.js 24.10 or newer:
bun install --frozen-lockfile
bun run release:checkAdd focused tests for observable behavior and document exported APIs. Pull requests should contain one coherent change and explain any public contract change.
The live harness is opt-in and never runs in CI. It validates a credential, builds a DNS plan, and prints the plan without mutating provider state:
bun run test:live:cloudflare preview
bun run test:live:vercel previewBoth providers require these environment variables:
DOMAINKIT_LIVE_ZONEDOMAINKIT_LIVE_RECORD_NAMEDOMAINKIT_LIVE_RECORD_VALUEDOMAINKIT_LIVE_ALLOW_ZONE, exactly matching the zoneDOMAINKIT_LIVE_ALLOW_RECORD_NAME, exactly matching the record name
Cloudflare additionally requires DOMAINKIT_LIVE_CLOUDFLARE_ACCOUNT_ID and
DOMAINKIT_LIVE_CLOUDFLARE_TOKEN. Vercel requires DOMAINKIT_LIVE_VERCEL_TEAM_ID and
DOMAINKIT_LIVE_VERCEL_TOKEN. Keep credentials in a local secret manager or scoped process
environment; never commit them.
To apply a reviewed plan, set DOMAINKIT_LIVE_APPROVED_DIGEST to the approval digest printed by
preview and replace preview with apply. The harness recomputes the approval and refuses to apply
if the DNS plan, Cloudflare account or Vercel team, zone allowlist, or record-name allowlist differs.
Apply creates DNS state and does not delete it, so use an explicitly disposable record and clean it
up through the provider when testing ends.
While the public contract is pre-1.0, APIs may change directly. Once a stable contract is declared, breaking changes will be explicit and versioned.