CLI
@akhatmirzo/cli — set up the library in your project and copy ready-made blocks into your code.
@akhatmirzo/cli automates two things: wiring the library into your project (init) and copying
ready-made blocks — a login form, pricing, a dashboard — straight into your code (add). Blocks
don't live inside a package, they live in your files: change them however you like.
No install needed — run it with npx (or pnpm dlx, yarn dlx, bunx):
npx @akhatmirzo/cli init # packages + CSS setup
npx @akhatmirzo/cli list # available blocks
npx @akhatmirzo/cli add login pricing # copy blocks into your projectRequirements: Node.js 18.17+. The CLI itself has zero dependencies — only Node's built-in modules.
init
Run it in your project folder (next to package.json):
npx @akhatmirzo/cli initWhat it does:
- Checks for Tailwind CSS v4 (
tailwindcssinpackage.json). If it's missing or v3, it warns but keeps going. - Detects your package manager from the lockfile (
pnpm-lock.yaml,package-lock.json,yarn.lock,bun.lockb/bun.lock; parent folders are checked too, for monorepos). Without a lockfile it uses the manager that launched the CLI, otherwisenpm. - Installs
@akhatmirzo/uiand@akhatmirzo/tokens(skipped if already present). - Finds your global CSS file:
app/globals.css,src/app/globals.css,src/index.css,src/styles/globals.css,styles/globals.cssand a few more. If none is found it asks (or use--css). - Adds two lines to it — the tokens right after the Tailwind import, and
@sourceafter the imports:
@import 'tailwindcss';
@import '@akhatmirzo/tokens/theme.css'; /* added */
@source '../../node_modules/@akhatmirzo/ui/dist'; /* added */The @source path is computed relative to the CSS file. Existing lines are never added twice —
running init again is safe.
Then add the providers at your app root — see Installation.
add
npx @akhatmirzo/cli add login
npx @akhatmirzo/cli add login pricing --dir src/components/blocks- Each block is downloaded from the registry and written into
--dir(default:components/blocks). - All blocks are downloaded and validated first — if anything fails, nothing is written.
- If a file already exists, you're asked.
--overwritereplaces it without asking.--yesnever replaces existing files (they're skipped), so your code can't be lost by accident. - If a block needs extra packages (
react-hook-form,zod,recharts...) that aren't in yourpackage.json, the CLI offers to install them.
list
npx @akhatmirzo/cli listPrints the blocks grouped by category, with name and description. Browse them visually in the Blocks section.
Options
| Option | Description |
|---|---|
--cwd <dir> | Project folder (default: current directory) |
-y, --yes | Answer "yes" (package installs); existing files are still kept |
-o, --overwrite | add: overwrite existing files |
--no-install | Don't install packages — only print the install command |
-d, --dir <dir> | add: blocks folder (default: components/blocks) |
--css <file> | init: global CSS file (default: auto-detected) |
-r, --registry <url|dir> | Registry location (default: https://toolkit.akhatmirzo.uz/r) |
-h, --help | Help |
-v, --version | Version |
In non-interactive environments such as CI nothing is prompted: init requires --yes, while add
writes new files, skips existing ones and doesn't install packages (it prints the install command).
Colors are used only in a terminal and when NO_COLOR is not set. Messages are in Uzbek.
Registry and offline use
The registry is plain JSON: <registry>/index.json (the list) and <registry>/<name>.json:
{
"name": "login",
"title": { "uz": "Kirish", "en": "Login" },
"description": { "uz": "...", "en": "..." },
"category": "auth",
"dependencies": ["react-hook-form", "zod"],
"files": [{ "path": "login.tsx", "content": "..." }]
}Point --registry (or the AKHATMIRZO_REGISTRY environment variable) somewhere else — your own
server, a file:// URL or just a local folder:
npx @akhatmirzo/cli add login --registry ./registry
npx @akhatmirzo/cli list --registry https://example.com/rSecurity
The CLI only writes inside your project folder. File paths from the registry are strictly
validated: absolute paths, .. segments, dot-prefixed names and anything resolving outside
--dir are rejected, and writing outside through a symlink is blocked too. Package names are
validated as well and you're asked before anything is installed. If you use a third-party
registry, review the written code — it becomes part of your project.