Skip to content

CLI

The brutx-vue CLI helps you initialize BrutxUI in your project and add components with a single command.

Overview

bash
npx brutx-vue@latest <command>

The CLI automatically handles dependency installation, file creation, and configuration updates.

brutx-vue init

Initialize BrutxUI in your project. It sets up the base configuration:

bash
npx brutx-vue@latest init

The init command will:

  1. Detect your project framework (Vite, Nuxt, etc.)
  2. Install required dependencies (reka-ui, class-variance-authority, clsx, tailwind-merge, @lucide/vue)
  3. Create the cn() utility function in src/lib/utils.ts
  4. Inject --brutal-* CSS custom properties into your stylesheet
  5. Add BrutxUI styles (including Tailwind utility class layers) to your CSS
  6. Set up the component directory structure

Init also supports monorepo workspace detection. If a pnpm-workspace.yaml, lerna.json, or turbo.json file is found, the CLI will detect the workspace root and offer to install shared dependencies there while keeping component-specific dependencies in the current package. Use --workspace-root to explicitly specify the workspace root.

Options

FlagDescriptionDefault
--yes / -ySkip prompts and use defaultsfalse
--defaults / -dUse default configurationfalse
--cwd <path>Set working directoryCurrent directory
--force / -fForce overwrite existing configurationfalse
--silent / -sSilent outputfalse
--vscodeGenerate VS Code snippetsAuto-detected
--workspace-root <path>Specify monorepo workspace root directoryAuto-detected

brutx-vue add

Add individual components to your project:

bash
npx brutx-vue@latest add <component...>

Examples

Add a single component:

bash
npx brutx-vue@latest add button

Add multiple components:

bash
npx brutx-vue@latest add button card dialog input

Add all available components:

bash
npx brutx-vue@latest add --all

Version Pinning

Use the @ syntax to pin a component to a specific version. The string after @ is injected as a git ref (branch, tag, commit) into the registry source URL, so all component files are fetched from that ref:

bash
npx brutx-vue@latest add button@1.2.0

Interaction with --registry

@version only works with GitHub raw URL registries (matching https://raw.githubusercontent.com/{owner}/{repo}/{ref}/...). The CLI replaces the {ref} segment of the current --registry URL with the @version, leaving the rest of the path intact. This means it composes cleanly with custom forks:

bash
# Pull button from the v1.2.0 tag of your personal fork
npx brutx-vue@latest add button@1.2.0 \
  --registry https://raw.githubusercontent.com/<you>/<fork>/main/registry

If --registry is not a GitHub raw URL (e.g. a local path or self-hosted HTTP registry), using @version throws a REGISTRY_VERSION_UNSUPPORTED error. Remove @version or switch --registry to a GitHub raw URL.

Version mismatch warning

When the installed component version differs from the requested version, the CLI prints a warning (non-blocking):

text
⚠ Version mismatch: "button" is already installed at version 1.0.0, but you requested 1.2.0.

Version constraints in update

update skips version-pinned components by default (it should not silently change a ref the user explicitly locked). To update across versions, pass --across-versions:

bash
# Skips button@1.0.0 by default
npx brutx-vue@latest update

# Explicitly update across the locked version
npx brutx-vue@latest update --across-versions

Options

FlagDescriptionDefault
--allAdd all available componentsfalse
--yes / -ySkip confirmation promptsfalse
--cwd <path>Set working directoryCurrent directory
--overwriteOverwrite existing component filesfalse
--path <path> / -pSpecify the path to add components to
--silent / -sSilent outputfalse
--dry-runSimulate adding without writing filesfalse
--registry <registry> / -rSpecify registry path or URL
--no-cacheSkip registry cachefalse
--vscodeUpdate VS Code snippets with new componentsfalse

brutx-vue doctor

Check project configuration health and diagnose common issues:

bash
npx brutx-vue@latest doctor

The doctor command will check:

  1. Whether components.json exists and is valid
  2. Whether the $schema field is present
  3. Whether the $version config version is up to date
  4. Whether the style field is present
  5. Tailwind CSS file contains BrutxUI design tokens
  6. Whether configured alias paths point to real files/directories
  7. Whether required dependencies are installed (reka-ui, class-variance-authority, clsx, tailwind-merge)
  8. Whether the cn() utility function exists
  9. File integrity of installed components

Examples

Basic diagnostics:

bash
npx brutx-vue@latest doctor

Auto-fix fixable issues:

bash
npx brutx-vue@latest doctor --fix --yes

Apply only a specific fix:

bash
npx brutx-vue@latest doctor --fix-only add-schema

Output JSON format report:

bash
npx brutx-vue@latest doctor --json

Options

FlagDescriptionDefault
--cwd <path>Set working directoryCurrent directory
--fixAuto-fix fixable issuesfalse
--fix-only <fixId>Apply only the specified fix
--jsonOutput JSON format reportfalse
--yes / -ySkip confirmation promptsfalse
--silent / -sSilent outputfalse
--sbomGenerate a CycloneDX 1.5 SBOM and exit (skips doctor checks)false
--sbom-output <path>SBOM output file path./brutx-sbom.json

Output Example

text
Brutx-Vue Doctor

  [PASS] components.json exists — components.json found.
  [PASS] $schema field present — $schema field is present.
  [PASS] config version — Configuration version is 1.
  [PASS] style field present — style is "brutalism".
  [PASS] tailwind.css contains BrutxUI tokens — CSS file contains BrutxUI tokens.
  [PASS] aliases.components → @/components — Directory exists.
  [PASS] aliases.utils → @/lib/utils — File exists.
  [PASS] tailwindcss installed — ^4.3.0 installed.
  [PASS] reka-ui installed — ^2.9.9 installed.
  [PASS] cn() function exists — cn() function found.

  Summary: 10 passed, 0 warnings, 0 errors

Auto-Fixable Issues

IssueFix Action
Missing $schemaWrite schema URL
Missing or outdated $versionUpdate to current version
Missing styleSet to brutalism
CSS missing BrutxUI tokensInject CSS styles
Component directory missingCreate directory
Utils file missingCreate utils file
cn() function missingAdd cn() function

brutx-vue diff

Compare locally installed components against the latest registry versions:

bash
npx brutx-vue@latest diff [components...]

Examples

Compare a single component:

bash
npx brutx-vue@latest diff button

Compare multiple components:

bash
npx brutx-vue@latest diff button card dialog

Compare all installed components:

bash
npx brutx-vue@latest diff --all

Output JSON format:

bash
npx brutx-vue@latest diff --all --json

Options

FlagDescriptionDefault
--allCompare all installed componentsfalse
--cwd <path>Set working directoryCurrent directory
--registry <path> / -rSpecify local registry path
--jsonOutput JSON formatfalse
--silent / -sSilent outputfalse
--no-cacheSkip registry cachefalse

Output Example

Compare a single component:

text
Component Diff: button

  Status: MODIFIED (1 file changed)

  src/components/ui/button/Button.vue
    --- registry/src/components/ui/button/Button.vue
    +++ local/src/components/ui/button/Button.vue
    -  variant?: 'default' | 'destructive' | 'outline' | 'ghost';
    +  variant?: 'default' | 'destructive' | 'outline' | 'ghost' | 'link';
    +  loading?: boolean;

  Summary: 1 file modified, 0 files unchanged

Compare all components:

text
Component Diff Report

  MODIFIED (2)
    — button    (1 file changed)
    — card      (2 files changed)

  UP-TO-DATE (5)
    — badge
    — dialog
    — input
    — select
    — toast

  Summary: 2 modified, 5 up-to-date, 0 local-only

brutx-vue update

Check for and apply component updates from the registry. Components with local modifications will be flagged before overwriting:

bash
npx brutx-vue@latest update [components...]

Examples

Update a specific component:

bash
npx brutx-vue@latest update button

Update all outdated components without prompts:

bash
npx brutx-vue@latest update --all --yes

Preview which components have updates available:

bash
npx brutx-vue@latest update --dry-run

Options

FlagDescriptionDefault
--all / -aUpdate all outdated componentsfalse
--yes / -ySkip confirmation promptsfalse
--cwd <path>Set working directoryCurrent directory
--dry-runShow which components would be updated without writingfalse
--registry <registry> / -rSpecify registry URL
--no-cacheSkip registry cachefalse
--silent / -sSilent outputfalse
--across-versionsAllow updating version-pinned components across their locked version (see Version Pinning)false

brutx-vue list

List all installed components in your project, including file counts and dependencies:

bash
npx brutx-vue@latest list

Examples

List installed components:

bash
npx brutx-vue@latest list

Output as JSON:

bash
npx brutx-vue@latest list --json

Options

FlagDescriptionDefault
--cwd <path>Set working directoryCurrent directory
--jsonOutput JSON formatfalse
--silent / -sSilent outputfalse

Output Example

text
Installed Components

  Name        Files   Dependencies
  ──────────  ──────  ────────────────────────
  badge       2       reka-ui
  button      3       reka-ui, @lucide/vue
  card        2       none
  dialog      2       reka-ui, @lucide/vue

  4 component(s) installed

brutx-vue info

Show detailed information about a component, including registry metadata, local files, dependencies, and installation status:

bash
npx brutx-vue@latest info <component>

Examples

Show info for a component:

bash
npx brutx-vue@latest info button

Output as JSON:

bash
npx brutx-vue@latest info button --json

Options

FlagDescriptionDefault
--cwd <path>Set working directoryCurrent directory
--jsonOutput JSON formatfalse
--registry <registry> / -rSpecify registry path or URL
--silent / -sSilent outputfalse

brutx-vue remove

Remove installed components from your project. Also detects and cleans up orphaned files (composables, utilities, locales) that are no longer referenced by any remaining component:

bash
npx brutx-vue@latest remove <components...>

Examples

Remove a single component:

bash
npx brutx-vue@latest remove button

Remove multiple components:

bash
npx brutx-vue@latest remove button card dialog

Preview removal without deleting files:

bash
npx brutx-vue@latest remove button --dry-run

Options

FlagDescriptionDefault
--yes / -ySkip confirmation promptsfalse
--cwd <path>Set working directoryCurrent directory
--dry-runShow which files would be removed without deletingfalse
--silent / -sSilent outputfalse

brutx-vue create

Scaffold a new Vue 3 project with BrutxUI pre-configured. Creates the project, installs dependencies, and runs init automatically:

bash
npx brutx-vue@latest create <project-name>

Examples

Create a project with the default Vite + Vue 3 + TypeScript template:

bash
npx brutx-vue@latest create my-app

Create a Nuxt 3 project:

bash
npx brutx-vue@latest create my-app --template nuxt

Create a project using npm as the package manager:

bash
npx brutx-vue@latest create my-app --package-manager npm

Options

FlagDescriptionDefault
--template <template> / -tProject template (default, nuxt)default
--package-manager <pm>Package manager to use (pnpm, npm, yarn, bun)pnpm
--cwd <path>The directory to create the project inCurrent directory
--yes / -ySkip confirmation promptsfalse

components.json Configuration File

The components.json file is created by brutx-vue init and stores your project configuration. All CLI commands read this file to locate components, utilities, and styles.

json
{
    "$schema": "https://brutx-vue.dev/schema.json",
    "$version": 1,
    "style": "brutalism",
    "tailwind": {
        "config": "tailwind.config.js",
        "css": "src/assets/index.css"
    },
    "aliases": {
        "components": "@/components",
        "utils": "@/lib/utils",
        "composables": "@/composables"
    }
}
FieldDescription
$schemaJSON schema URL for IDE validation and autocompletion.
$versionConfiguration format version. Used by doctor to detect outdated configs that may need migration.
styleThe design style variant. Currently only brutalism is supported.
tailwind.configPath to your Tailwind CSS config file. Empty string for Tailwind v4 (no config file needed).
tailwind.cssPath to your main CSS file where BrutxUI design tokens are injected.
aliases.componentsImport alias for the components directory (e.g. @/components).
aliases.utilsImport alias for the utility file containing cn() (e.g. @/lib/utils).
aliases.composablesImport alias for the composables directory (e.g. @/composables).

Global Options

The following options apply to all commands and must be placed before the subcommand:

bash
npx brutx-vue@latest [global-options] <command> [command-options]
FlagDescriptionDefault
--verboseShow detailed error output (equivalent to -v)false
--dry-runGlobal dry-run: simulate all write operations without touching disk (stacks with command-level --dry-run)false
--require-signatureStrict signature mode: fail when manifest signature is invalid (default is warn, see Supply Chain Security)false
--verbose-level <level>Verbose output level (1=steps, 2=cache/network details, 3=stack traces)0
-vEquivalent to --verbose-level 1
-vvEquivalent to --verbose-level 2
-vvvEquivalent to --verbose-level 3

Global dry-run

The --dry-run global flag activates dry-run semantics for all commands without needing to add --dry-run after each subcommand. Can also be activated via the BRUTX_DRY_RUN=1 environment variable:

bash
# These two are equivalent
BRUTX_DRY_RUN=1 npx brutx-vue@latest add button
npx brutx-vue@latest --dry-run add button

When activated, add/update/remove only print paths that would be written; no files are modified.

Verbose levels

Control output verbosity via -v/-vv/-vvv or the BRUTX_VERBOSE=<n> environment variable:

LevelLabelMeaning
1[STEP]Step-level, e.g. "resolving dependencies"
2[DETAIL]Cache/network details, e.g. "cache hit button@v1"
3[TRACE]Stack/debug details

Audit Log

After add/remove/update/diff commands execute, a JSONL record is appended to .brutx/audit.log containing:

  • timestamp: ISO timestamp
  • command: command type (add/remove/update/diff)
  • components: list of components operated on
  • registrySource: registry source
  • success: whether the operation succeeded
  • dryRun: whether it was a dry-run
  • error: error message on failure

doctor reads the last 5 failure records from the audit log as diagnostic clues:

bash
npx brutx-vue@latest doctor

Example output:

text
⚠ audit log health — 1 recent failure(s) in audit log: update(button).
  Latest: update failed at 2026-07-16T02:30:00Z — Network unreachable

Supply Chain Security: Signature & SBOM

P1-6 introduces manifest Ed25519 signature verification and CycloneDX 1.5 SBOM generation to detect supply chain tampering.

Manifest Signature

At registry build time, registry-manifest.json carries signature + keyId fields holding an Ed25519 signature over the integrity field. The CLI automatically verifies the signature when fetching the manifest.

Trusted Public Keys

Trusted public keys are injected via the BRUTX_REGISTRY_PUBLIC_KEYS environment variable (JSON array):

bash
BRUTX_REGISTRY_PUBLIC_KEYS='[{"keyId":"v1","publicKey":"<base64-SPKI-DER>"}]' \
  npx brutx-vue@latest add button

publicKey is a base64-encoded SPKI DER (single-line, easy to embed in JSON). When the env var is unset, verification degrades to skip (backward compatible).

Default warn vs strict mode

On signature failure, the default behavior is warn (print a warning and continue) so that projects without configured keys are not blocked during migration:

text
[Signature] Manifest signed with unknown keyId "v1". No matching trusted public key found.
  (use --require-signature to enforce)

To fail hard on signature errors, activate strict mode:

bash
# Via flag
npx brutx-vue@latest --require-signature add button

# Or via environment variable
BRUTX_REQUIRE_SIGNATURE=1 npx brutx-vue@latest add button

In strict mode, a signature failure throws REGISTRY_SIGNATURE_INVALID (exit 1). The integrity field still backstops tampering: even when signature verification is skipped, tampered content will fail because integrity no longer matches.

Key Rotation

Public keys are indexed by keyId. When rotating keys:

  1. New key signs the manifest: add the new public key to BRUTX_REGISTRY_PUBLIC_KEYS
  2. Transition period: the old key remains in the list, old manifests stay trusted
  3. Revoke the old key: remove it from the env var

SBOM Generation

Registry SBOM (build time)

pnpm --filter brutx-registry-vue build automatically generates packages/registry/registry/registry-sbom.json containing:

  • All registry components (type: application, bom-ref: brutx:<name>)
  • All npm dependencies (type: library, bom-ref: npm:<dep>)
  • dependencies arrays referencing other bom-refs to form the dependency graph
  • integrity field (sha256 over bomFormat/specVersion/components)
  • manifestIntegrity field binding the SBOM to the corresponding registry-manifest.json integrity

serialNumber is a random UUID regenerated each build, excluded from integrity computation, and added to the build:verify diff exclusion set.

Project SBOM (doctor --sbom)

doctor --sbom generates an SBOM for installed components, written to ./brutx-sbom.json (customize with --sbom-output):

bash
npx brutx-vue@latest doctor --sbom
npx brutx-vue@latest doctor --sbom --sbom-output ./reports/sbom.json

It reads installed component versions, dependencies, registryDependencies, and integrity from the .brutx/components.json manifest and emits a CycloneDX 1.5 SBOM. Errors out if no components are installed.

Available Components

accordion, activity-log-page, alert, alert-dialog, auth-card, avatar, badge, before-after, blog-card, blog-list-page, breadcrumb, brutalist-hero, button, calendar, card, card-3d, carousel, chat-bubble, checkbox, code-block, combobox, command, cookie-consent, copy-to-clipboard, counter, dashboard-shell, dashboard-stats, data-table, dialog, dropdown-menu, empty-state, faq-section, feedback-form, file-card, footer-section, form, gallery-section, glitch-text, hardcore-input, header-section, input, kbd, kanban, loading, marquee, not-found-page, number-input, overview-page, pagination, popover, pricing-section, profile-page, progress, quick-actions, radio-group, result, scratch-card, scroll-area, search-widget, select, separator, settings-page, sheet, skeleton, sketchy-chart, slider, spinner, stepper, switch, table, tabs, tags-input, testimonial-card, textarea, timeline, toast, toggle, toggle-group, tooltip, tree-view, upload, waitlist-page

Brute force builds.