@mihcm/cli
v0.4.4
Published
CLI: copy-paste primitives from @mihcm/ui into a consumer project. `npx @mihcm/cli add Button`.
Readme
@mihcm/cli
Copy-paste primitive workflow for the MiHCM Design System.
This package lets consumers copy MiHCM primitive source into their own repo while keeping tokens and theme packages installed as the shared source of truth.
Current release
Current published version: 0.4.3.
Currently aligned with the @mihcm/[email protected] release train on public npm. Documents tailwind-variants and now sonner as approved helpers for copied primitives — if copied component source imports either, install it in the consuming app instead of replacing with ad-hoc alternatives. The copy registry tracks the rebuilt sonner-backed Toast and the polished MainSidebar source.
npx @mihcm/cli init --target next
npx @mihcm/cli doctor
npx @mihcm/cli add button
npx @mihcm/cli add link
npx @mihcm/cli add button text --out src/components
npx @mihcm/cli listWhat it does
Copies the source .tsx (and .native.tsx) for each primitive from your installed @mihcm/ui package into your project, so you can own and edit them locally — the same model as shadcn/ui.
After mihcm add button in a fresh project, you get:
components/ds/
├── Button.tsx
├── Button.native.tsx
└── internal/
└── cn.tsThe native variant ships alongside the web variant; Metro / React Native bundlers pick it up automatically via the .native.tsx extension. The shared cn helper is copied once and reused across components.
Recent additions and fixes
- Added the semantic
linkprimitive to the copy registry so consumer apps can use an accessible anchor component instead of styling buttons as links. - Supports the expanded component catalog, including app-shell, data, overlay, form, and AI-safe primitives.
- Keeps copied components tied to the installed
@mihcm/uiversion instead of fetching remote source. - Preserves helper imports from copied source, including
class-variance-authorityandtailwind-variants. doctorchecks stale registry overrides and theme import issues before consumers start copying components.initwrites starter setup for Next, Vite, and Expo targets without writing package tokens.
Prerequisites
- These three public npm packages installed in your project — they ship the source the CLI reads, the tokens, and the Tailwind preset:
pnpm add @mihcm/ui @mihcm/theme @mihcm/tokens- These runtime peers (also peer-deps of
@mihcm/ui):
pnpm add react class-variance-authority tailwind-merge clsx- If you copy
Toast.tsx, also install sonner —@mihcm/ui's Toast wraps it for the full upstream feature set:
pnpm add sonnerCommands
init --target <next|vite|expo>
Writes safe starter config files for a consumer app. It never writes package tokens or registry overrides.
| Flag | Default | What it does |
|---|---|---|
| --target, -t <target> | next | Target runtime: next, vite, or expo. |
| --force, -f | off | Overwrite files that already exist. |
| --dry-run | off | Print what would be written without touching disk. |
doctor
Checks the current project for common consumer setup issues:
- project
.npmrcdoes not route MiHCM packages to GitHub Packages; - project
.npmrcdoes not contain tokens; - required MiHCM packages are in
package.json; - theme CSS is imported from
@mihcm/theme/globals.css.
add <component...>
Copies one or more primitives into your project.
| Flag | Default | What it does |
|---|---|---|
| --out, -o <dir> | components/ds | Output directory, relative to cwd. |
| --force, -f | off | Overwrite files that already exist. |
| --dry-run | off | Print what would be written without touching disk. |
Component names are case-insensitive. Run mihcm list for the current set.
list
Prints every primitive the CLI knows about.
help
Prints the usage block. Also runs when no command is given.
Security contract
- Never write npm tokens into project
.npmrc. - Never fetch component source from arbitrary URLs.
- Resolve source from the installed package in
node_modulesso consumer lockfiles control the version. - Use
--dry-runbefore copying into an unfamiliar repo. - Use
--forceonly when the diff is reviewed.
Why copy-paste, not install?
Two reasons (full rationale: ADR-005):
- You own the code. Tweak variants, add an icon slot, change focus rings — none of which require a fork of the package. Editing copied components is just editing your repo.
- Tree-shaking that actually works. No metadata, no compiled cruft — just the source TSX a bundler can dead-code-eliminate down to the bytes you use.
Tokens and the Tailwind preset stay on the install track because they're meant to be a single source of truth — you shouldn't be copy-pasting --color-primary into your repo.
Copied primitives may use either class-variance-authority for simple root variants or tailwind-variants for slot-heavy and compound variants. Install tailwind-variants too when the copied source imports it. Do not replace those helpers with ad hoc class maps.
Distribution model
The CLI resolves your installed @mihcm/ui package from node_modules (walking up from cwd) and reads source files out of it. We deliberately don't fetch source from the private repo; the public npm package already contains the copyable files, and going through npm install keeps lockfile-pinned versions in the loop.
Maintainer checklist
When adding a component to the CLI:
- Ensure the primitive is exported by
@mihcm/ui. - Ensure source files are included in the UI package
fileslist. - Add the component to the CLI registry/list output.
- Check dry-run output for web and native files.
- Update this README and package docs.
- Add a changeset before publishing.
Build
cd src
pnpm -F @mihcm/cli build
pnpm -F @mihcm/cli typecheck