CLI
stepwise-ui fetches component source from the registry and writes it into your project. It is the only piece of Stepwise that is an npm package.
Running it
Use it through npx. There is nothing to install globally.
The CLI finds your project by walking up from the current directory until it hits a package.json, so it works from a subdirectory. If there is no package.json anywhere above you, it stops with an error rather than guessing.
init
The starting point. Opens a searchable list of every component: type to filter, Tab to select, Enter to confirm. Anything you already have is marked, and what you pick is installed straight away.
It also handles the project setup. If your stylesheet is missing the dark-mode variant, or tsconfig.json is missing the @/ alias, it offers to add them and asks first. Say no and it prints what to add yourself.
On the tsconfig edit: adding the alias means rewriting the file, and it comes back as standard 2-space JSON. Any comments in it are lost, since JSON has no comments, and the formatting is normalised, so the diff can be larger than the one line you expected. A file too broken to parse is left untouched with a message instead. On a fresh create-next-app none of this is noticeable; on a hand-tuned config, decline the prompt and paste the alias in yourself.
Needs a terminal. There is nothing for a picker to read in CI or an agent session, so init exits with a pointer to add and list --all rather than hanging on a prompt nobody can answer. add never edits your config for the same reason: it runs unattended.
add
The non-interactive path, for when you already know the name or are scripting. Names match the URL of each docs page.
A run looks like this:
list
What this project already has, matched by filename against the registry:
Pass --all for the whole registry instead. That is the non-interactive counterpart to init, so scripts and agents can discover components without a picker:
How resolution works
Components can build on each other. date-picker uses calendar, so asking for the first brings the second. The CLI walks that graph before writing anything and reports what it pulled in under Also required:.
Shared files like lib/utils/cn.ts ship with every component that imports them, so the same path can arrive many times in one run. It is written once. Cycles and diamonds are handled by resolving to a set, so a component that appears twice is still fetched once.
If one name in a multi-component run is wrong, the others still install. The bad name is reported and the exit code is non-zero.
Existing files
The CLI compares content before touching anything.
Identical file: skipped silently. Nothing to say.
Different file: left alone and reported, so a local edit is never overwritten by accident.
Pass --yes (or -y) to overwrite. Commit your work first - the CLI does not keep a backup.
Dependencies
npm packages a component imports - motion, @lisse/react, clsx - are installed automatically, in a single install at the end of the run rather than once per component. Packages you already have are not reinstalled.
Your package manager is detected from the lockfile: bun.lockb, pnpm-lock.yaml, or yarn.lock, falling back to npm.
Framework packages are not installed. If a component needs react and the project does not have it, the CLI says so and leaves it to you. Installing a React version into someone's project is a worse outcome than the error.
If the install itself fails, the exact command is printed so you can run it yourself. Files are already written at that point.
Where files go
Components land in components/stepwise/, shared primitives in components/stepwise/primitives/, and helpers in lib/. These paths are fixed, because the generated files import each other through the @/ alias.
Move things afterwards if you like - they are your files. You will need to update the imports.
Configuration
There is no config file, and nothing to set up. The one setting exists for a single situation: you have forked this repo, changed a component, and want to install your version instead of the published one.
Run the site locally, then point the CLI at it with STEPWISE_REGISTRY_URL:
Everything installs from your copy instead. Unset it and you are back on the published registry. If you are not forking Stepwise, you never need this.
Command reference
| Command | What it does |
|---|---|
init | Browse every component in a searchable picker and install what you select. |
add <components...> | Add one or more components by name, with their dependencies. |
add <components...> --yes | Overwrite files that differ, without prompting. Alias: -y |
list | List the Stepwise components already in this project. Alias: ls |
list --all | List every component in the registry instead. Alias: -a |
--version | Print the installed CLI version. |
--help | Usage and examples. Works on subcommands too. |
Source and issues on GitHub.