The Wensity CLI.
The Wensity CLI copies component, primitive, and block source into your project. You run it with your package manager. There is no runtime package to add to dependencies, and no provider to wire up after install.
Registry-aware commands read from the hosted registry. add and update write typed .tsx files into paths defined in wensity.json, rewrite internal imports to your aliases, and install declared package dependencies with your detected package manager. Free components and primitives install without login. Pro components and premium blocks require a dashboard API token and an active component license.
This reference covers every command, the config file the CLI expects, global flags, and the errors you are most likely to see in real projects.
Install the CLI
Run the CLI on demand. No global install is required.
$pnpm dlx wensity@latest --help
Use @latest for all commands, including presets. Current releases include --preset, apply --preset, preset inspect, and --template.
Command overview
Create wensity.json and a local cn() helper once per project. Optional --preset and --template.
Apply a wsty1… preset to an existing Wensity project (style + CSS only).
Decode a preset code and print fonts, packages, and resolved tokens.
Save or remove a dashboard API token for Pro installs.
Print registry components or premium blocks. Supports --json.
Download source into your repo. add skips existing files. update overwrites them.
New to Wensity? Start with Getting started for the browse-to-ship path, or Installation for framework requirements and peer dependencies.
wensity init
Initialise Wensity in a Next.js or Vite project. Writes wensity.json and a small cn() utility.
$pnpm dlx wensity init
Run this once per repo. The command detects Tailwind config and global CSS paths, sets default aliases for @/components/wensity and @/lib/utils, and installs clsx and tailwind-merge unless you pass --no-install.
With a preset, init also writes version + style into wensity.json and upserts the delimited --primitive-* CSS block into your configured Tailwind CSS file (fetched from the pinned free button payload, no separate CSS endpoint).
Useful flags:
| Flag | Description |
|---|---|
| --preset <code> | Apply a validated wsty1… style preset (icons, radius, fonts, control-solid colors). Merges style when config already exists without requiring --force. Generate codes in the Create preset studio. See the Create preset guide. |
| --preset-file <path> | Same as --preset, reading a code or codec JSON payload from disk (CI escape hatch). |
| --template <name> | Scaffold a minimal app before init: next, vite, astro, or react-router. |
| --dry-run | Previews files and dependencies without writing anything. |
| --force | Overwrites an existing wensity.json or utility file. Required for plain init when config already exists. Not required for init --preset style merges. |
| --no-install | Writes config files but skips package manager installs. |
| --api-url | Points init at a staging or self-hosted Wensity origin. |
Presets
Supported flow:
- Configure icons, radius, fonts, and control-solid colors in the Create preset studio.
- Run
npx wensity@latest init --preset <wsty1-code>from your project root (add--template nextwhen scaffolding). - For an existing Wensity project, prefer
npx wensity@latest apply --preset <wsty1-code>. - Inspect
wensity.json(version,style) and the--primitive-*block in your CSS file. - Run
npx wensity add <primitive>. Future adds reuse stored colors, radius, fonts, and Tabler/Lucide choice.
Behavior by project state:
| State | Action | Result |
|---|---|---|
| Clean project | init or init --preset | Creates config (+ style/CSS when preset). Defaults: Tabler, medium radius, site/system fonts, shipped control-solid colors. |
Existing wensity.json | plain init | Refuses without --force. |
Existing wensity.json | apply --preset | Preferred for style-only updates. Merges style and upserts primitive CSS. No helper scaffolding. |
Existing wensity.json | init --preset | Also merges style and upserts primitive CSS. Paths/aliases stay. Installed component source is not rewritten. |
Legacy config (no version/style) | add | In-memory defaults (Tabler, medium). No crash. |
| After style change | update <primitive> | Rewrites local source with the current icon library + CSS overrides. Review the diff. |
Scope and contracts:
- Presets apply to UI primitives only. Premium
/componentsand blocks ignorestyle.iconLibraryand stay byte-identical under Tabler vs Lucide project config. - Installed files are full editable open-code. No
@wensity/uiimport, no Wensity runtime provider, no account required for free primitives. @base-ui/reactand the selected icon package are ordinary npm dependencies owned by your project.- Custom font stacks must pass the shared grammar (no
;,{{,url(, or CSS breakouts). Prefer built-in font IDs. - Invalid, truncated, oversized, or unsupported-version preset codes exit non-zero with an actionable message (regenerate in the studio).
- If your
package.jsonalready lists the opposite icon library, the CLI warns and does not uninstall it, your app code may still use it. New Wensity primitive installs import only the configured library. - Phosphor/Hugeicons and automatic icon migration of already-installed files are deferred.
wensity apply
Apply a preset to a project that already has wensity.json:
$pnpm dlx wensity apply --preset wsty1.YOUR_CODE
Updates stored style and the --primitive-* CSS block without scaffolding helper files. Requires an existing Wensity config, run init first on a clean project.
wensity preset inspect
Decode a wsty1… code before you apply it:
$pnpm dlx wensity preset inspect wsty1.YOUR_CODE
Add --json for machine-readable output.
CLI vs shadcn
| Wensity CLI | Public shadcn registry (@wensity/*) | |
|---|---|---|
| Stored Wensity presets | Yes, wensity.json style | No |
| Lucide selection | Yes, CLI-time transform + dependency swap | No, payloads stay Tabler-canonical |
| Full editable source | Yes | Yes |
@wensity/ui runtime | Never | Never |
| Base UI npm dependency | Ordinary local dep when declared | Ordinary local dep when declared |
| Premium components | Token + license; outside primitive presets | Never exported |
These paths are complementary, not feature-parity. Use the Wensity CLI when you need presets or Lucide delivery. Use shadcn when you already run a shadcn registry workflow and only need a quick free Tabler primitive.
wensity login
Authenticate the CLI with a dashboard API token. The command validates the token against /api/cli/whoami, then stores credentials locally at ~/.config/wensity/credentials.json with 0600 permissions.
$pnpm dlx wensity login
For CI or scripted setup, pass the token non-interactively:
pnpm dlx wensity login --token "$WENSITY_TOKEN"
You can also read the token from WENSITY_TOKEN when the flag is omitted. Override the credential file path with WENSITY_CREDENTIALS_FILE if your environment requires it.
After login, Pro component installs use /api/cli/<slug>. Premium block installs use /api/cli/blocks/<slug>. If a token is revoked in the dashboard, the next authenticated request fails immediately.
wensity whoami
Verify the saved token and print the current account and plan.
$pnpm dlx wensity whoami
Use wensity whoami --json for machine-readable output in setup scripts. The JSON payload includes apiBaseUrl and the resolved credentials path.
wensity list
Print registry entries grouped by access. Components are the default resource type.
$pnpm dlx wensity list
List premium blocks separately:
$pnpm dlx wensity list --type block
wensity list --json returns the full registry payload. That is the same shape the website uses for listings and internal tooling.
wensity add
Download a component, primitive, or block into your project. Components and primitives land under src/components/wensity by default. Blocks land under src/components/wensity/blocks.
Install a free component:
$pnpm dlx wensity add liquid-multimodal-input
Install a premium block after login:
$pnpm dlx wensity add monolith-hero --type block
How source is resolved:
Free components and primitives download from the public registry when no token is saved, or when saved credentials are rejected for a free slug. Pro components require wensity login and download from /api/cli/<slug>. Premium blocks always require login and download from /api/cli/blocks/<slug>.
The CLI rewrites Wensity internal imports to your configured aliases, writes missing helper files in the same pass, and installs declared npm dependencies with your detected package manager unless you pass --no-install. For UI primitives, it also applies stored style overrides to the --primitive-* CSS block and, when style.iconLibrary is lucide, rewrites Tabler icon imports to Lucide with a mandatory dependency swap.
wensity add refuses to overwrite files that already exist. Pass --dry-run to preview planned writes and dependency installs without touching disk. Pass --force to overwrite during add when you explicitly want that behavior.
wensity update
Re-download a component or block you already added. This command overwrites the local copy so your git diff remains the review surface. For primitives, update re-applies the current wensity.json style (icon library transform + CSS overrides).
$pnpm dlx wensity update liquid-multimodal-input
$pnpm dlx wensity update button
Review the resulting diff before committing, especially if your team edits installed files directly. init --preset never rewrites installed source, use update when you change icon library after files already exist.
wensity logout
Remove the saved credential file from your machine.
$pnpm dlx wensity logout
Global options
These flags work across commands where noted in wensity --help:
| Option | Description |
|---|---|
| --api-url <url> | Overrides the Wensity app origin. Defaults to https://ui.wensity.com. Also available as WENSITY_API_URL. |
| --registry <url> | Overrides the registry endpoint in wensity.json for the current command. |
| --type component|block | Selects components or blocks for list, add, and update. Defaults to component. |
| --dry-run | Prints planned writes and installs without changing files. |
| --no-install | Writes source files but skips package manager installs. |
| --force | Overwrites generated files during init or add. |
| --json | Prints machine-readable output for list and whoami. |
wensity.json
Generated by wensity init. Commit this file. It tells the CLI where to write components, where shared utilities live, which Tailwind files to reference, which registry origin to call, and (when present) primitive style settings.
{"$schema": "https://ui.wensity.com/schema/wensity.json","version": 1,"registry": "https://ui.wensity.com/api/registry","components": "src/components/wensity","utils": "src/lib/utils","tailwind": {"config": "tailwind.config.ts","css": "src/app/globals.css"},"aliases": {"components": "@/components/wensity","utils": "@/lib/utils"},"style": {"iconLibrary": "tabler","radius": "medium","fonts": {"sans": "site","display": "site","mono": "system-mono"}}}
Legacy configs without version / style keep working, the CLI applies Tabler + medium defaults in memory. Keep aliases aligned with your TypeScript paths in tsconfig.json.
Custom registry URL
Change the registry field when you mirror the public registry or host internal components behind your own origin. The endpoint must return the same JSON shape as https://ui.wensity.com/api/registry.
Block listings resolve to /api/blocks on the same origin unless you pass --registry explicitly for a list, add, or update command.
Pin a known registry snapshot behind your CDN for reproducible installs, or extend the index with internal-only slugs. The CLI still expects the same metadata and source payload fields Wensity publishes today.
Typical workflow
Configure primitive settings with Create preset when you want Lucide, non-default radius, fonts, or control-solid colors. Run wensity init --preset <code> (or plain wensity init) once per project and commit wensity.json. Use wensity apply --preset <code> on existing projects. Install free components and primitives with wensity add <slug>. Before Pro component or block installs, create a dashboard API token and run wensity login.
Then run wensity add <pro-slug> or wensity add <block-slug> --type block. Import components from @/components/wensity/<slug> and blocks from @/components/wensity/blocks/<slug>, then review the git diff. Use wensity update <slug> when you want a fresh upstream copy that respects the current preset.
Troubleshooting
Most failures are authentication, project config, or network related. Start with wensity whoami, then check origin and file conflicts.
Token rotated or revoked
If wensity whoami fails after rotation, log out and authenticate again with a fresh dashboard token.
$pnpm dlx wensity logout$pnpm dlx wensity login --token "$WENSITY_TOKEN"$pnpm dlx wensity whoami
Revoked tokens fail immediately because /api/cli/whoami and authenticated source endpoints validate the token hash before returning payload.
Wrong API origin
The CLI reads WENSITY_API_URL, --api-url, or the registry origin embedded in wensity.json. Verify the host when you work behind a proxy or against staging.
$pnpm dlx wensity whoami --api-url https://ui.wensity.com$WENSITY_API_URL=https://ui.wensity.com pnpm dlx wensity list
File already exists
wensity add stops when a target file already exists. Use wensity update <slug> when you want to replace the local copy with the latest registry source, then review the diff.
Missing dependencies
Run wensity add <slug> --dry-run to see planned files and package dependencies. If you used --no-install, install the printed packages yourself before importing the component.
Invalid or unsupported preset
Preset codes must start with wsty1. and pass the shared codec + style validators. If init or apply fails with Invalid preset: …, regenerate the code in the Create preset studio. Do not hand-edit encoded payloads. Custom font stacks that include ;, {, or url( are rejected, prefer built-in font IDs.
Partial primitive CSS markers
If your globals CSS has a broken or half-edited Wensity Primitive Tokens block, add fails with a clear error instead of corrupting the file. Restore the start/end markers or remove the partial block, then re-run.
Opposite icon package already installed
When style.iconLibrary is lucide but @tabler/icons-react is still in package.json (or the reverse), the CLI warns and continues. It never uninstalls the opposite package automatically. Installed Wensity primitive source imports only the configured library.
Error reference
Authenticated endpoints return structured JSON errors. The CLI prints the message and exits with code 1.
{"error": "token_revoked","message": "API token has been revoked. Create a fresh dashboard token and run wensity login again."}
Common error codes:
| Code | Meaning |
|---|---|
| missing_token | A Pro endpoint was called without a bearer token. |
| invalid_token | The token hash does not match a stored credential. |
| token_revoked | The token was revoked in the dashboard. |
| token_user_missing | The token owner no longer exists. |
| pro_license_required | The account has no active component license. |
| component_not_found | The component slug is missing from the registry. |
| block_not_found | The block slug is missing from the registry. |
| component_source_unreadable | Component source storage cannot be read server-side. |
| block_source_unreadable | Block source storage cannot be read server-side. |