# DomainKit

> Add custom domains to your app with reviewable DNS plans and React flows.

## Compare

- [DomainKit vs Entri, a library in your app or a managed modal](https://domain-kit.dev/compare/entri): Entri is a hosted modal covering 70+ DNS providers. DomainKit is an open-source library for Cloudflare and Vercel. Compare cost, control, and coverage.
- [Cloudflare for SaaS and DomainKit work together](https://domain-kit.dev/compare/cloudflare-for-saas): Cloudflare for SaaS issues certificates and routes customer hostnames. DomainKit writes the CNAME and validation records in the customer's DNS zone.
- [Domain Connect and DomainKit, two ways to set up a customer's DNS](https://domain-kit.dev/compare/domain-connect): Domain Connect is an open template protocol each DNS provider onboards. DomainKit writes through the customer's own grant. How they differ.
- [Copy-paste DNS instructions and where they break](https://domain-kit.dev/compare/manual-dns): Webflow, Ghost, Framer, Resend, and Postmark all ask customers to copy DNS records by hand. Where that breaks, and what to do about it.

## Components

- [Components](https://domain-kit.dev/components): React components for custom domain setup: a full flow, a DNS records table, and status badges. Copy them into your app with shadcn and preview them live.

### Registry

- [Registry](https://domain-kit.dev/components/registry): Copy React DNS components, such as a records table, status badge, and copy button, from the DomainKit shadcn registry and use your own data and styles.
- [Domain flow](https://domain-kit.dev/components/registry/domain-flow): A complete React custom domain setup flow: connect DNS, review the records, approve once, apply, and watch them verify. Copy it with shadcn.
- [Provider row](https://domain-kit.dev/components/registry/provider-row): A React row that shows which DNS provider serves a domain, the account the records go to, and a menu to disconnect. Install it with shadcn.
- [Records table](https://domain-kit.dev/components/registry/records-table): A React table of the DNS records a domain needs, each with its plan or observed status, a copy button per value, and the reason a record is blocked.
- [Plan action](https://domain-kit.dev/components/registry/plan-action): A React button that approves a DNS plan's digest and applies it in one press, naming how many records it will add and reporting what landed.
- [Connect dialog](https://domain-kit.dev/components/registry/connect-dialog): A React dialog that lets a customer connect their Cloudflare or Vercel DNS account with a token or OAuth, copied into your project with shadcn.
- [Disconnect dialog](https://domain-kit.dev/components/registry/disconnect-dialog): A React dialog that disconnects a customer's DNS provider and, if they choose, removes the records DomainKit added, from one reviewed cleanup plan.
- [Domain field](https://domain-kit.dev/components/registry/domain-field): A React domain input that completes from the zones your customer's connected DNS accounts reach, and names the account the records go to.
- [Outcome](https://domain-kit.dev/components/registry/outcome): A React component that turns a failed domain setup step into a plain heading, what to do next, and a retry control. Copy it with the shadcn CLI.
- [Provider artwork](https://domain-kit.dev/components/registry/provider-artwork): Map each DNS provider id to your own logo in React, drawn as the mark itself with no tile around it. Used by the provider row and picker.
- [DNS table](https://domain-kit.dev/components/registry/dns-table): A responsive React DNS records table with type, name, value, priority, purpose, and status columns for domain setup screens. Install with shadcn.
- [DNS operation](https://domain-kit.dev/components/registry/dns-operation): A React card showing one planned DNS change, its record, purpose, and any conflict, so customers review it before your app applies the plan.
- [DNS status](https://domain-kit.dev/components/registry/dns-status): A React badge that shows whether a DNS record is satisfied, missing, mismatched, or unchecked after a DNS check. Copy it with the shadcn CLI.
- [Provider mark](https://domain-kit.dev/components/registry/provider-mark): A React wrapper that gives a DNS provider logo an accessible label and consistent size for provider pickers and connection cards.
- [Copy value](https://domain-kit.dev/components/registry/copy-value): A React copy-to-clipboard component for DNS names, targets, and tokens, with an accessible button. Install it with the shadcn CLI.
- [Async state](https://domain-kit.dev/components/registry/async-state): Loading, empty, and error state components for React domain setup screens. Copy them with shadcn; your app owns fetching, retries, and messages.

## Customers

- [How Samva sets up customer domains with DomainKit](https://domain-kit.dev/customers/samva): How Samva, an email API, lets customers add a sending domain without copying DNS records. The records, the flow, and what the customer approves.

## Docs

- [Add custom domains to your app](https://domain-kit.dev/docs): Connect a DNS provider, review the exact records your product needs, apply only what the customer approved, and keep credentials and policy in your app.
- [Your first plan, approval, and receipt](https://domain-kit.dev/docs/quickstart): Run the whole lifecycle against an in-memory provider, then read the plan, the receipt, and the readiness it produced.
- [Glossary](https://domain-kit.dev/docs/glossary): The words DomainKit uses for requirements, plans, approvals, receipts, connections, attachments, and observation.

### Build

- [Mount DomainKit in your app](https://domain-kit.dev/docs/guides/host-integration): Compose the lifecycle layer, write the Identity service, mount the route group in your API, and handle the provider callback the browser is sent to.
- [Persistence and custody](https://domain-kit.dev/docs/guides/storage): Choose a Storage implementation, seal credentials, and decide whether DomainKit, your pipeline, or your deploy runs the migrations.
- [Write a provider](https://domain-kit.dev/docs/guides/implement-provider): Turn a DNS provider's HTTP API into one declarative definition, declare its auth methods, and prove it with the conformance runner.
- [Test against the seam](https://domain-kit.dev/docs/guides/testing): Drive the real services with in-memory fakes, render UI against a recording transport, and check your own implementations with the conformance runners.
- [Troubleshooting](https://domain-kit.dev/docs/guides/troubleshooting): What each failure means in practice, why an interactive connection stalls, why DNS never becomes ready, and the checks that usually explain both.

### Concepts

- [Plans, approval, and receipts](https://domain-kit.dev/docs/core/plans): How a plan is built from your requirements, what its four operations mean, what an approval binds it to, and what a receipt proves about an apply.
- [Setting up many domains at once](https://domain-kit.dev/docs/core/batches): How a batch plans several domains together, binds one digest to one consent, applies with bounded concurrency, and resumes whatever did not land.
- [Connections and attachments](https://domain-kit.dev/docs/core/connections): How a provider credential becomes a connection, how a domain attaches to a zone, and how a second domain reuses what the customer already connected.
- [Verification and readiness](https://domain-kit.dev/docs/core/verification): What DomainKit observes for a domain, how provider evidence differs from public DNS, how a requirement's status is decided, and when to look again.
- [Cleanup](https://domain-kit.dev/docs/core/cleanup): Why removing records is its own plan, what a receipt proves, and what happens to a record someone edited by hand.
- [Failure reasons](https://domain-kit.dev/docs/core/errors): The one error type DomainKit raises, the seventeen reasons it carries, the HTTP status each answers with, and what a host should do about each one.
- [DomainKit and Domain Connect](https://domain-kit.dev/docs/core/domain-connect): What the Domain Connect protocol does, why DomainKit does not implement it today, and what DomainKit does instead.

### Providers

- [Connect a customer's Cloudflare DNS](https://domain-kit.dev/docs/providers/cloudflare): Let customers connect Cloudflare with OAuth or an API token so your SaaS can add their DNS records. Pairs with Cloudflare for SaaS hostnames.
- [Connect a customer's Vercel DNS](https://domain-kit.dev/docs/providers/vercel): Let customers connect Vercel with an access token or a marketplace integration so your SaaS can add records to their Vercel DNS zones.

### React

- [React](https://domain-kit.dev/docs/react): Headless hooks that run the custom-domain lifecycle over a transport your server owns, and the shadcn registry that renders them in your design system.
- [Controllers](https://domain-kit.dev/docs/react/controllers): The four hooks behind the flow, the tagged states they expose, the commands they take, and how an attempt is abandoned when its inputs change.
- [Composition](https://domain-kit.dev/docs/react/composition): Write the domain surface yourself over the flow hook, place its pieces in your own layout, and add a domain through the zone picker your accounts already reach.
- [Words and outcomes](https://domain-kit.dev/docs/react/presentation): Replace any sentence the flow puts on screen through the message catalog, and render a failed step from the title and description its reason resolves to.
- [The transport](https://domain-kit.dev/docs/react/transport): Build the browser-side view of your routes, declare which capability groups exist, and adapt a Promise client.
- [Shadcn registry](https://domain-kit.dev/docs/react/registry): Copy the styled domain flow and the plain DNS display components into your project with the shadcn CLI, then own their markup, classes, and layout.

### Reference

- [Entry points](https://domain-kit.dev/docs/reference/entry-points): The public DomainKit imports, what each entry point carries, where each one runs, and the runtime and peer versions they need to be installed with.
- [domainkit](https://domain-kit.dev/docs/reference/core): Every namespace the package root exports, what each one owns, how the composed layer is built, and the failure shape every operation raises.
- [domainkit/server](https://domain-kit.dev/docs/reference/server): The mountable route group and its twenty-five endpoints, the Identity service a host implements, the wire schemas, the options, and the Web handler.
- [domainkit/client](https://domain-kit.dev/docs/reference/transport): The browser transport over the routes you mounted, its optional capability groups, the connect methods it sends, and the Promise adapters.
- [domainkit/testing](https://domain-kit.dev/docs/reference/testing): The fakes, the recording transport, and the conformance runners that let host tests drive the real services instead of stubbing global fetch.
- [@domainkit/capsuledb](https://domain-kit.dev/docs/reference/capsuledb): DomainKit's Storage on PostgreSQL as one declarative CapsuleDB capsule, with its options, its eight tables, and the three ways to run its migrations.
- [@domainkit/react](https://domain-kit.dev/docs/reference/react): The React namespaces, the flow hook and what it returns, the controllers and their states, the message catalog, and the read-only contract.
- [Provider contract](https://domain-kit.dev/docs/reference/providers): What a provider definition must implement, which record types travel portably, and how provider failures are classified.

## Guides

- [SaaS custom domain setup, step by step](https://domain-kit.dev/guides/custom-domain-onboarding): A code-first guide to SaaS custom domain setup. Declare the records, let the customer connect DNS, review and approve, apply, and verify.
- [Custom domains for multi-tenant apps on Vercel](https://domain-kit.dev/guides/vercel-custom-domains): Let customers use their own domain on your Vercel app. Add the hostname with Vercel's API, then write the DNS records in their Cloudflare or Vercel account.
- [Set up your customers' email sending domains](https://domain-kit.dev/guides/email-domain-setup): What a customer's email sending domain needs, which DNS records to write, and how to review, apply, and verify them from your app.

## Agent resources

- [llms-full.txt](https://domain-kit.dev/llms-full.txt): The full Markdown of every page in one file.
- [Page Markdown](https://domain-kit.dev/index.md): Append `.md` to any page URL to fetch that page as raw Markdown.
- [JSON API](https://domain-kit.dev/api/docs/pages.json): Page index of the JSON docs API; each entry links the page's JSON and Markdown forms. Described by the OpenAPI document at https://domain-kit.dev/openapi.json.
- [Agent skills](https://domain-kit.dev/.well-known/agent-skills/index.json): Agent Skills discovery index of the skills this site publishes.
- [API catalog](https://domain-kit.dev/.well-known/api-catalog): RFC 9727 linkset of the APIs documented here.
- [AI catalog](https://domain-kit.dev/.well-known/ai-catalog.json): ARD manifest of the agent-facing resources on this site (MCP server, skills, APIs).
- [agent-readability.json](https://domain-kit.dev/agent-readability.json): Manifest of every agent-facing artifact on this site.
- [Sitemap](https://domain-kit.dev/sitemap.xml): Every indexable page URL with its last-modified date.
