Citty CLI
Quick Start
npm install citty `@bomb.sh/tab` `@clack/prompts`
Minimal command:
tsimport { defineCommand, runMain } from 'citty'; export default defineCommand({ meta: { name: 'greet', description: 'Say hello' }, args: { name: { type: 'string', description: 'Your name', required: true } }, run({ args }) { console.log(`Hello, ${args.name}!`); }, });
Critical Rules
- Every command exports default
defineCommand()— no exceptions - Lazy-load subcommands —
() => import('./cmd').then(m => m.default) - Check
isCancel()after every@clack/promptscall — never skip - Citty handles all arg parsing — no external parsers
- Architecture is opt-in — only suggest
cli/structure when the user asks for project layout or scaffolding. Single-file CLIs are valid. - Gate
tab()behindprocess.argv[2] === 'complete'— the adapter eagerly resolves lazy subcommands, defeating rule 2 on every startup
Architecture (only when user asks for structure)
See architecture for the full cli/ layout with commands, prompts, and lib directories. Do not impose this structure unless the user explicitly asks for scaffolding or project organization.
Workflow
- Define commands — commands
- Add prompts if interactive — prompts
- Add spinners/progress for long-running work — tty-ui
- Wire tab completion — tab-completion
- Scaffold
cli/if multi-command — architecture - Configure bin entry — sidecar setup
- Verify — run with
--helpto confirm command registration - Ship it — CI gates, versioning, npm or binary release — release
References
- Architecture — Structure and responsibilities
- Entrypoint — runMain + tab completion wiring
- Commands — defineCommand, args, subcommands
- Prompts —
@clack/promptsreusable modules - Tab Completion —
@bomb.sh/tabcitty adapter, completion protocol, per-shell install (compinit ordering, fish autoload), lazy-loading gate - TTY UI — spinners and progress:
@clack/promptsspinner first,@bomb.sh/ttyinline regions and layout for richer feedback - Sidecar Setup — bin entry, build config
- Citty API — Resolvable, plugins, CLIError
- Release — CI gates, Changesets/release-please, npm + binary distribution
- Versioning — named schemes (SemVer/CalVer), 0.x vs 1.0, pre-releases, which bump, decision matrix, recording the policy
- Update Command — ask-first self-update: install-mode routing, streaming download (stall timeout, resumable retry), checksum-verified atomic swap, passive banner

