Sometime in the last few days, the two npm packages that make up the customdomain.ai SDK passed a thousand downloads between them.
What that number is, precisely
A milestone post is a bad place to be vague about arithmetic, so: that figure is registry downloads across both packages over the last thirty days, straight from npm's public API. It is not a thousand companies, a thousand developers, or a thousand production deployments, and we would be inventing something if we said it were.
Two things are worth knowing if you go and check the numbers yourself, which you can, because they are public.
The first is that @customdomain/react declares customdomain-js as a
dependency. Installing the React wrapper downloads both. So the two package counters overlap
heavily and cannot simply be added to get a population — the core package's own figure, 586 for the
last thirty days, is the superset that every install passes through.
The second is that npm counts machines, not minds. Registry mirrors, security scanners and CI runners all pull packages, and they pull hardest the moment a new version lands: 438 of this package's first 597 downloads arrived on three publish days. Anyone presenting a raw npm number as an adoption metric is overstating it, including us if we weren't saying this.
What the number does mean is real, if smaller than it looks: the SDK is published, installable, and being pulled by more than just its authors, four weeks after first release. That's the milestone. It's an early one.
Why the SDK exists
Custom domains look like a small feature until you build one. Then you find that "let the customer point their domain at us" is a euphemism for a dozen problems that have nothing to do with your product.
The sharpest of those problems is the zone apex. A CNAME record is illegal at the
root of a zone — RFC 1034 §3.6.2 — and it is not a stylistic rule but a structural one: a
CNAME cannot coexist with the SOA and NS records every zone
root must carry. So when a customer wants acme.com and not app.acme.com,
the ordinary answer doesn't exist.
The DNS industry's response has been a set of non-standard record types that paper over it —
ALIAS, ANAME, Cloudflare's CNAME flattening — each proprietary, each named
differently, and none universal. Two of the largest consumer registrars, GoDaddy and Namecheap, have
no such type at all. For a customer on either, an apex custom domain is not a configuration step; it
is a conversation about A records and IP addresses, or a redirect to a subdomain.
This is the kind of thing that is invisible in a demo and expensive in a support queue. Testing
your integration on app.staging.example.com will never reveal it. It shows up when your
first real customer types their real root domain.
The SDK's job is to know these differences so your product doesn't have to. It detects the customer's DNS provider, decides whether their apex can be served at all, and either drives the change automatically or renders exactly the records that provider needs, in that provider's own vocabulary.
What the first month taught us
We shipped the SDK, then went and read what happened when someone actually embedded it in a product. Three things stood out, and none of them were in the plan.
The automatic path is narrower than the industry implies. Provider coverage and one-click are not the same claim, and the gap between them is where integrators get surprised. Automatic configuration requires the customer's registrar to support a delegation standard like Domain Connect — and most consumer registrars, where most small-business domains actually live, do not. The honest shape of the product is that a minority of connections are one click and the majority are a well-designed manual flow with automatic verification behind it. We would rather build the manual flow properly than pretend it is rare.
Silent correctness bugs are the expensive ones. The worst defect we found in that month didn't throw an error anywhere: a write path that quietly repointed an integrator's third-party apex record at our own edge. No failed request, no log line — just a customer's root domain resolving somewhere with no origin for it. We now hold a rule that every fix ships with a test proven to fail against the old behaviour, because a test that has never seen the bug proves nothing about it.
"Pending" is a product surface. DNS propagation is not instant and nobody believes a spinner. Most of the perceived quality of a custom-domain flow is in what you show a user during the ninety seconds when nothing has happened yet.
Where to start
The SDK is Apache-2.0 and the source is on GitHub.
npm install customdomain-js
The quickstart goes from an empty project to a connected domain, and the widget and SDK reference covers the embed in detail. If you are weighing this against building it in-house, the apex and provider notes are the part we would read first.
Thanks to everyone who installed it early, filed something, or told us where it was wrong. The next post gets to use a bigger number, and we'll be just as specific about what it counts.