Skip to content

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.

npx uitheme-cli info
npx uitheme-cli info --cwd apps/web

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.

npx uitheme-cli init --dry-run
npx uitheme-cli init

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.

npx uitheme-cli init --cwd apps/web --base radix --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.

npx uitheme-cli list
npx uitheme-cli list --base radix --language js --json

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.

npx uitheme-cli add theme-toggle theme-selector --dry-run
npx uitheme-cli add theme-toggle theme-selector

Select the output when the detected defaults do not match your app:

npx uitheme-cli add color-theme-selector --base radix --tailwind 4 --language ts

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 as keep <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.

npx uitheme-cli add theme-toggle --overwrite --dry-run
npx uitheme-cli add theme-toggle --overwrite --yes

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.

npx uitheme-cli diff theme-toggle
npx uitheme-cli diff
npx uitheme-cli diff --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.

npx uitheme-cli migrate
npx uitheme-cli migrate --cwd apps/web --json
npx uitheme-cli migrate --yes

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.

OptionBehavior
--cwd <app>, -c <app>Select the app to migrate. Defaults to the current directory.
--dry-run, --previewShow the migration plan without applying it. This overrides --yes.
--yes, -yApply a safe migration plan. Without this flag, migration stays in preview mode.
--jsonPrint a structured migration report. This does not authorize writes.
--help, -hShow 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.

OptionValues 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

OptionBehavior
--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, --previewPreview init or add without writing files or installing packages. diff is always read-only.
--yes, -yApply an init or add plan without questions. Files that differ from the uitheme version are kept.
--overwriteReplace files that differ from the uitheme version, without a question.
--jsonPrint structured output for list or a plan for init, add, and diff. info always prints JSON. This flag does not enable preview mode.
--help, -hShow help without running the selected command.

Combine JSON output with a preview when you need a plan without writes:

npx uitheme-cli add theme-toggle --json --dry-run

Environment variables

VariableBehavior
UITHEME_REGISTRY_URLUse another registry for every command. --registry wins when you set both.
UITHEME_WEB_VERSIONInstall 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.

UITHEME_WEB_VERSION=next npx uitheme-cli init
UITHEME_REGISTRY_URL=http://127.0.0.1:4000/r npx uitheme-cli add theme-toggle

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

npx uitheme-cli --help
npx uitheme-cli add --help
npx uitheme-cli migrate --help
npx uitheme-cli --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

CodeMeaning
0The command completed, or a preview completed without errors.
1The command failed. Read the error before retrying.
2Manual steps remain. Setup may have applied safe changes. Migration with manual diagnostics does not write files.