v0.5.1

CLI

Use the Paubha CLI to init a project and add components.

The Paubha CLI fetches source from the registry on paubha.tech and copies it into your codebase, with no runtime package.

npx paubha@latest [command]

init

Use the init command to set up configuration and shared dependencies for an existing project.

init creates components.json, writes the design tokens and Tailwind v4 @theme mapping, adds the cn() helper, and installs clsx, tailwind-merge, and class-variance-authority.

npx paubha@latest init

What it writes (defaults from components.json):

  • styles/tokens.css: primitives + semantic tokens (light and dark)
  • styles/theme.css: Tailwind v4 @theme mapping
  • lib/cn.ts: cn() helper
  • components.json: registry URL and path aliases

It also adds the tokens.css/theme.css @imports to your global stylesheet, immediately after @import "tailwindcss";, and records that file as tailwind.css in components.json.

Existing files are skipped unless you pass --force. Safe to re-run: the CSS imports aren't duplicated on a second pass.

Options

Usage: paubha init [options]

write tokens.css, theme.css, cn(), wire them into your global CSS, and install
core dependencies

Options:
  --cwd <path>  target directory (default: current directory)
  --force       overwrite existing files (default: false)
  -h, --help    display help for command
OptionDescription
--cwd <path>Run against another project root
--forceOverwrite existing files

add

Use the add command to copy components (and their dependencies) into your project.

Requires components.json; run init first.

npx paubha@latest add button

Add multiple components at once:

npx paubha@latest add button avatar tabs

add fetches {registry}/{name}.json, walks registryDependencies recursively, dedupes shared files, and installs any npm packages listed on those items. Example: add field also pulls in input.

Unknown names fail with the list of components the registry currently publishes.

When it's done, add prints the import line for what it just copied, derived from the file it actually wrote.

Restrained (-v2) variants

The -v2 items — select-v2, accordion-v2, popover-v2, pagination-v2, tag-input-v2 — are additive, quieter variants that ship inside the base component's file, not next to it. add select-v2 writes components/ui/select/select.tsx, the same file add select writes, and you get both Select and SelectV2 from it either way:

import { SelectV2, SelectTriggerV2, SelectContentV2 } from "@/components/ui/select";

So adding both is a no-op the second time (already up to date), not a conflict. If you've edited the file locally, add leaves your version alone and tells you to pass --force.

Options

Usage: paubha add [options] <components...>

copy one or more components into your project

Arguments:
  components    component name(s), e.g. button avatar

Options:
  --cwd <path>  target directory (default: current directory)
  --force       overwrite existing files (default: false)
  -h, --help    display help for command
OptionDescription
--cwd <path>Run against another project root
--forceOverwrite existing files
# Overwrite a component you already customized
npx paubha@latest add button --force

# Target another project root
npx paubha@latest add button --cwd ./apps/web

components.json

init writes this at the project root. add reads it on every run.

{
  "$schema": "https://paubha.tech/schema.json",
  "registry": "https://paubha.tech/r",
  "aliases": {
    "components": "components/ui",
    "lib": "lib"
  },
  "tailwind": {
    "tokens": "styles/tokens.css",
    "theme": "styles/theme.css",
    "css": "app/globals.css"
  }
}
FieldDescription
registryBase URL for registry JSON (/r/{name}.json)
aliases.componentsWhere UI files land
aliases.libWhere helpers like cn.ts land
tailwind.tokens / tailwind.themePaths init uses for the CSS files
tailwind.cssGlobal stylesheet init adds the token @imports to (auto-detected, then saved)

In a project with a src/ folder, init writes everything under src/ (for example src/components/ui, src/lib, src/styles) so it sits inside the @/* alias. If tsconfig maps @/* to the project root, it keeps root paths. add and init warn when components.json points outside the alias.

Override the registry for a single command without editing the file:

PAUBHA_REGISTRY_URL=http://localhost:3000/r npx paubha@latest add button

PAUBHA_REGISTRY_URL wins over components.json.

Registry

Components are served from https://paubha.tech/r/{name}.json, following the shadcn registry schema. You can also install with the shadcn CLI:

npx shadcn@latest add https://paubha.tech/r/button.json

Building the registry (contributors)

The monorepo source of truth is packages/registry. After changing a component:

pnpm build:registry

That emits apps/www/public/r/*.json for the docs site to serve.