All docs
Concepts · Tokens

Tokens

Tokens are the contract between Caret and the visual layer. Components never write hex codes or magic numbers — they read tokens through the active theme. Re-skin the entire system by overriding a single object.

Categories

TokenLives atOverride entry
colorsregistry/tokens/colors.tstheme.colors
motionregistry/tokens/motion.tstheme.motion
symbolsregistry/tokens/symbols.tstheme.symbols
spacingregistry/tokens/spacing.tstheme.spacing
typographyregistry/tokens/typography.tstheme.typography

Colors

Caret separates brand color (truecolor, fixed — your CLI's recognizable accent) from semantic colors (ANSI-named, so they harmonize with the user's terminal theme).

KeyDefaultPurpose
accent.default#5882f7Brand accent — used for prompts, anchors, primary CTAs
accent.muted#3a5fb8Lower-emphasis accent for hover or disabled states
semantic.success.ansigreenSuccess messages, completed steps
semantic.warning.ansiyellowDeprecation, soft warnings
semantic.danger.ansiredErrors, failures, destructive actions
semantic.info.ansiblueInformational messages
fgterminal defaultForeground — Caret never overrides
dimANSI dimMuted text — descriptions, labels
Truecolor only for brand
Caret emits ANSI names (green, red) for semantic colors so they pick up the user's theme. Only accent is a fixed truecolor value — that's the part that makes a Caret CLI recognizable across any terminal.

Motion

Every animation is bounded and gated by reduced-motion detection. Tokens come in two flavors: durations (how long a transition runs) and frame rates (how often a stepped animation ticks).

KeyDefault (ms)Used by
duration.instant60Tight feedback (cursor blink window)
duration.fast120Color/border transitions
duration.default200Spinner morph, prompt resolve
duration.slow300Reveals, modal enters
spinnerFrameMs80Braille spinner step interval
blinkMs1050Block cursor blink cycle

Symbols

Symbols are part of the brand. The manifesto says: never customize them. They are listed here for reference, not because they're meant to be replaced.

KeyGlyphWhere used
anchor^Brand mark — banner heads, prompt frames
state.successSuccessful steps, success() messages
state.failureFailed steps, error() messages
state.warningwarning() messages, alert(kind: warning)
state.infoinfo() messages, alert(kind: info)
state.cancelledUser-cancelled prompts
marker.selectedSelected radio / multi-select item
marker.unselectedUnselected radio / multi-select item
progress.arrowList arrow variant, focus indicator
structure.gutterQuote, error, alert left gutter

Overriding tokens

Two ways to apply a custom theme:

src/index.ts
import { caret } from './caret'

// 1. Globally — affects every Caret call from this point on
caret.theme.set({
  colors: {
    accent: { default: '#FF6B35' },
  },
  symbols: {
    anchor: '◆',
  },
})

// 2. Per call — one-off override, no global state
spinner('Deploying', deploy, {
  theme: { colors: { accent: { default: '#10B981' } } },
})

Theme overrides are merged shallowly per top-level key. You only specify the leaves you want to change — Caret fills the rest from the default theme.


Continue with the Principles the tokens reflect, or jump to the component catalog to see the tokens applied in real previews.