CLI
Set up your app, install component source, and review changes from the terminal.
The uitheme-cli package provides the uitheme command. Run it with your package
runner. Use Node.js 22.18 or later and an existing app with Tailwind CSS 3.4 or 4.
See Installation for runtime and provider setup.
The CLI supports Next.js App Router, TanStack Start, Vite React, Vite Vue, and
Nuxt 4. Registry controls require uitheme-web 2.x. Install the current runtime
with npm install uitheme-web@latest.
info
Show the detected framework, language, package manager, Tailwind version, component base, and file paths. This command prints JSON and does not change files.
Use the project options to resolve an ambiguous result. The CLI reads app configuration without executing it.
init
Set up the framework provider, theme CSS, and uitheme.json configuration.
For React, the CLI creates theme-provider.tsx (or .jsx) one folder above the
installed controls, for example src/components/theme-provider.tsx. It exports a
ThemeProvider that wraps UIThemeProvider.
In a Vite entry, the CLI places ThemeProvider directly inside
<StrictMode>, around your other providers. If your app already has a
provider file or a cn utility that differs, the CLI asks before it replaces
the file. If you keep your file, the CLI prints the code to add by hand.
The first installation creates a shared cn utility when it is missing. The CLI
reuses the utils alias in components.json, or uses lib/utils in the source
folder. Later installs reuse it and repair a missing file. A valid callable cn
export is preserved, including when --overwrite is set. If validation cannot
resolve an import, fix that import before replacing the file.
Review the plan before applying changes.
For React, the CLI selects the base that the app already uses. It selects Radix
when the app depends on radix-ui or @radix-ui/*, and Base UI when the app
depends on @base-ui/react. If the app has both or neither, the shadcn style in
components.json decides: base-* styles select Base UI, and other styles
select Radix. Otherwise, the CLI uses Base UI. Set --base to choose another
base. Vue uses Reka.
Interactive runs can ask for a framework or component base when a choice is needed.
For unattended runs, provide explicit choices and --yes.
The CLI does not create an app or upgrade Tailwind. It preserves existing source and reports setup steps that need manual changes.
list
List the available components for the detected or selected base, Tailwind major, and source language. This command reads the registry and does not install files.
JSON output contains each component's name, title, and description.
Use --revision to inspect a recorded registry revision.
add
Install one or more components and their required helpers and dependencies. The source belongs to your app after installation.
Select the output when the detected defaults do not match your app:
The CLI uses one immutable registry revision for the component and its dependencies.
It records file hashes in uitheme.json to detect later local edits.
When a file differs from the uitheme version, the result depends on the run:
- In a terminal, the CLI asks for each file: Keep my file (the default), Overwrite, or Show the diff.
- With
--yes, or in CI, the CLI keeps your files, lists them, and exits with code 2. - With
--overwrite, the CLI replaces the files without a question. - With
--dry-run, the plan shows each file askeep <path> (...; --overwrite replaces it).
An unedited control from an older revision updates without a question. Its hash shows that you did not change it.
If the app has no uitheme.json, add asks whether to run init first. Without
a terminal, add stops and tells you to run uitheme init.
The CLI keeps a dependency that your app already has when its version range
is compatible with the controls. Otherwise, the plan shows an update, for example
update lucide-react ^0.300.0 -> ^1.61.0. A major update has a note, because it
can change other imports from that package in your app. Review the plan before
you confirm it. An older uitheme-web major is not updated; run
migrate first.
If dependency installation fails, the CLI restores the touched source files, package manifests, and lockfiles.
diff
Show source differences without writing files or installing dependencies.
Pass component names or omit them to review the components recorded in uitheme.json.
This command stays read-only with --yes or --overwrite.
JSON output contains the installation plan rather than the text diff.
migrate
Preview supported legacy imports and dependency declarations before moving to v2.
Migration previews changes by default. Add --yes to apply a safe plan.
Custom control props and unknown provider contexts require manual changes. When migration reports these cases, it does not write files. Follow the migration guide before replacing legacy controls. Migration does not run the package manager. Update the lockfile after applying its dependency changes.
Migration has its own options. Project and registry options from other commands do not apply.
| Option | Behavior |
|---|---|
--cwd <app>, -c <app> | Select the app to migrate. Defaults to the current directory. |
--dry-run, --preview | Show the migration plan without applying it. This overrides --yes. |
--yes, -y | Apply a safe migration plan. Without this flag, migration stays in preview mode. |
--json | Print a structured migration report. This does not authorize writes. |
--help, -h | Show migration help. |
Project options
These options apply to info, init, list, add, and diff.
Values can use --option value or --option=value.
Explicit flags override saved uitheme.json choices. Saved choices override
compatible component configuration, then automatic detection.
| Option | Values and behavior |
|---|---|
--cwd <app> | Select an existing app. Defaults to the current directory. The -c alias is available only for migrate. |
--framework <name> | vite-react, vite-vue, next, tanstack, or nuxt. Select a supported framework installed in the app. |
--base <name> | base-ui or radix for React; reka for Vue. |
--language <name> | ts or js. Select the language of the installed component source. |
--tailwind <major> | 3 or 4. Match the Tailwind major already installed in the app. |
--package-manager <name> | npm, pnpm, yarn, or bun. Select the package manager for dependency installation. |
--css <file>, --css-file <file> | Select the global theme stylesheet. Both names set the same option. |
--tailwind-config <file> | Select the Tailwind configuration file, such as the config used by Tailwind 3.4. |
--components-dir <dir> | Select where the CLI writes component source. Shared destinations must stay inside the detected workspace and have an owning package manifest. |
--alias-prefix <alias> | Set the import prefix used for installed controls. |
--color-format <format> | css for complete CSS colors; hsl-channels for HSL channel tokens. |
Registry and output options
| Option | Behavior |
|---|---|
--revision <revision> | Select an immutable registry revision for list, add, or diff. Omit it to use the registry's current stable revision. |
--registry <url> | Use another registry, for example a local build. The URL must use https, or http for localhost and 127.0.0.1. |
--dry-run, --preview | Preview init or add without writing files or installing packages. diff is always read-only. |
--yes, -y | Apply an init or add plan without questions. Files that differ from the uitheme version are kept. |
--overwrite | Replace files that differ from the uitheme version, without a question. |
--json | Print structured output for list or a plan for init, add, and diff. info always prints JSON. This flag does not enable preview mode. |
--help, -h | Show help without running the selected command. |
Combine JSON output with a preview when you need a plan without writes:
Environment variables
| Variable | Behavior |
|---|---|
UITHEME_REGISTRY_URL | Use another registry for every command. --registry wins when you set both. |
UITHEME_WEB_VERSION | Install uitheme-web from a dist-tag, a version, or a packed .tgz file. The default is uitheme-web@latest. |
The CLI prints the registry URL and the runtime when you change them.
The CLI always installs the UITHEME_WEB_VERSION value, even when the app
already has uitheme-web. A .tgz path records a file: path in
package.json. Use it only for local tests, and keep the variable set for
later commands in that app.
Help and version
-h is an alias for --help. -v is an alias for the top-level --version.
Version flags are top-level commands, not options for add or other commands.
Exit codes
| Code | Meaning |
|---|---|
0 | The command completed, or a preview completed without errors. |
1 | The command failed. Read the error before retrying. |
2 | Manual steps remain. Setup may have applied safe changes. Migration with manual diagnostics does not write files. |

