All docs
Overview · Getting started

Getting started

Caret is a copy-paste design system for command-line tools. You run npx caret-cli init to scaffold a new CLI, then caret add <component> for each primitive — prompts, spinners, tables, errors. The components land in your repo as plain TypeScript files; you own them from there.

Why Caret

The web has shadcn/ui. The terminal has nothing equivalent — every CLI invents its own colors, spinners, error messages, and prompts, and the result looks like five libraries glued together. Caret is the missing layer: one opinionated visual identity, one token system, one set of primitives that respect NO_COLOR, narrow terminals, and screen readers without you opting in to anything.

Install

Caret has no runtime dependency. The CLI is a one-shot installer — it scaffolds a project or copies a single component, then exits.

sh
# scaffold a new CLI with Caret preinstalled
npx caret-cli init my-cli

# add a component to an existing project
npx caret-cli add prompt
npx caret-cli add spinner

# list every component the registry knows about
npx caret-cli list

See Install for the full breakdown of what init creates and how the registry resolves component files.

Your first CLI

After caret init my-cli, the project compiles and runs out of the box. The starter src/index.ts looks like this:

src/index.ts
import { prompt, success, spinner } from './caret'

const name = await prompt.text({
  label: 'Project name',
  validate: (v) => v.length > 0 ? null : 'Required',
})

await spinner('Deploying', async () => {
  await deploy(name)
}, { onSuccess: 'Deployed' })

success(`${name} is live`)

Three primitives, no provider, no theme object you forgot to pass down. The rest of the manual is on this site — start with Principles for what Caret will and won't do, then Tokens for how to skin it.

How it works

Caret has four layers, top-down:

  • Components — React components rendered with Ink. Each one is one file you can read in a single sitting. They write inline output (scrollback-friendly, pipe-friendly), not fullscreen.
  • Tokens — colors, motion, symbols, spacing, and typography. The component layer never hard-codes hex values; everything routes through the token system, so a single setTheme() call re-skins the entire tool.
  • Capabilitylib/capability.ts detects TTY, NO_COLOR, narrow terminals, and reduced motion. Every component consults it before painting; that's why colors degrade through truecolor → 256 → ANSI 16 → plain without your code knowing.
  • Spec — every component is documented in specs/<name>.md as the source of truth. If you fork a component or port Caret to another language, the spec is what binds them.

Next

Pick a direction:

  • CLI — every command, every flag.
  • Principles — the ten rules every Caret decision comes back to.
  • Tokens — the palette, motion, and symbol set you'll override.
  • AI-native workflow — drop caret.md into your repo and Claude / Cursor / Copilot produce on-brand Caret code on the first try.
  • Component catalog — 80+ primitives with live previews.