CLI
Run it with your package manager’s runner — pnpm dlx, npx, yarn dlx or bunx. There is nothing to install globally.
Commands
| Command | What it does |
|---|---|
| init | Writes components.json, the cn() utility and the design tokens. |
| add <names…> | Installs components and everything they depend on. |
| list | Shows the registry, marking what you already have. |
| update [names…] | Compares installed components against the registry. |
| agents [targets…] | Writes the catalogue for the coding agents working in this project. |
| login [key] | Stores a licence key, for components that require one. |
| logout | Removes the stored licence key from this machine. |
| whoami [--check] | Reports whether this machine is signed in. |
Flags
| Flag | What it does |
|---|---|
| --registry <url> | A registry base URL, or a directory on disk. |
| --cwd <path> | Run against a different project root. |
| --yes | Accept defaults and never prompt. For CI. |
| --overwrite | Replace files you have edited. Says what it discards. |
| --skip-install | Write files without installing npm packages. |
Your edits are safe
add records a hash of every file it writes. That is what lets update tell three things apart: a file you have not touched, one you have edited, and one that changed upstream.
Re-running add on an untouched project does nothing. Re-running it after you have edited a component leaves your version alone and says so.
up to date src/components/ui/spinner.tsx
locally modified src/components/ui/button.tsx
up to date src/components/ui/calendar.tsx
! Only locally modified files differ; none were touched.
Re-run with --overwrite to replace them and lose those edits.Licensed components
Components that require a licence are listed in the registry like any other — with their description, what they depend on and how many files they are — but their source is served only to a licence holder. login checks the key against the registry before storing it, so a bad key fails when you paste it rather than days later during an install.
The key is stored in your own config directory, readable only by you, and never in the project: a key in components.json is a key in git. For CI, set DOWEL_TOKEN from your secrets store instead — it takes precedence over anything stored, which is also what logout will tell you if it is still set.
Private registries
--registry takes an HTTPS URL or a path on disk, so a fork or an internal mirror works without forking the CLI. It can also be set once in components.json.
@dowel-ui/registry builds one. An organisation declares its own components and extends this registry, and the result is a single URL serving both — so add acme-callout installs their component and pulls in whatever it depends on from upstream. A local item replaces an upstream one of the same name, and the build reports which, because doing that by accident is expensive.
The build refuses to emit a file it cannot read, an import written against the installed path rather than the authored one, or a component that imports something it never declared. Each of those would otherwise fail in a consumer’s repository, where it is hardest to trace.
What it will not do
- Install into a Tailwind v3 project. The tokens use
@theme, which v3 cannot parse. - Install into a JavaScript project. The published source is TypeScript; a half-working transform would be worse than a clear refusal.
- Overwrite a file you have edited, without
--overwrite.