@llui/cli
v0.2.0
Published
LLui CLI — add registry components (`llui add button`) to an LLui app, shadcn-style
Maintainers
Readme
@llui/cli
llui add <item> — copy registry components into your LLui app.
This is shadcn/ui's distribution model: components are source you own, not a
dependency you import. It fits LLui better than it fits React, because the copied file
is compiled by your @llui/vite-plugin — so it gets view lowering, the compile-time
lint rules, and the agent metadata ($ms / $ss / __lluiVariants) that a precompiled
library cannot give you.
pnpm add -D @llui/cli
pnpm llui init
pnpm llui list
pnpm llui add button card dialogThen import the tokens in your app CSS — not styles/theme.css:
@import 'tailwindcss';
@import '@llui/components/styles/tokens.css';
@import '@llui/components/styles/tokens-dark.css';theme.css is the opt-in baseline stylesheet. Its [data-scope][data-part] rules are
unlayered, and unlayered CSS beats @layer utilities — importing it alongside registry
components makes every one of their classes lose, with nothing to tell you.
Commands
| | |
| -------------------- | ----------------------------------------------------------------------------------------- |
| llui init | Write components.json. --ui/--lib set target dirs, --alias sets an import prefix. |
| llui add <item...> | Copy items and their registryDependencies. --overwrite, --dry-run. |
| llui list | Show what the registry offers. |
All commands accept --registry <url|path> and --cwd <dir>.
components.json
{
"registry": "https://llui.dev/r",
"paths": { "ui": "src/components/ui", "lib": "src/lib" }
}Add "aliases": { "ui": "@/components/ui", "lib": "@/lib" } only if your tsconfig
declares those paths. Without it the CLI rewrites the registry's @/lib/utils import to
a relative specifier computed from where the file landed. That is the default, not a
fallback: an alias the project does not declare produces a file that type-checks
nowhere, which is a worse outcome than a longer path.
Safety
llui addnever overwrites. The copied file is your source and is expected to have been edited; a secondaddreports it as skipped.--overwriteis the opt-in.- Registry file targets are validated at load. A registry is remote third-party
content, so
..and absolute paths are rejected before anything is written. - Unknown registry keys are ignored, so a registry that is ahead of your CLI still installs rather than failing closed.
Using a different registry
The registry format is a subset of shadcn's registry-item.json. Point at any host, a
local directory, or a checkout:
llui add button --registry ./registry
llui add button --registry https://example.com/rA local source may leave file contents on disk (files[].path); a remote one must serve
them inlined (files[].content), which scripts/build-registry.mjs produces.
