CLIs are the interfaces developers use most and design least. Terminal Kit is a component library for the terminal — spinners, tables, prompts, progress, forms — with the opinions of a design system and the ergonomics of a good React library.
Why it exists
Every team I've worked on eventually ships an internal CLI, and every one of them reinvents the same pieces badly: a hand-rolled spinner that tears on resize, a table that breaks on wide unicode, a prompt that swallows Ctrl-C. The pieces aren't hard — they're just fiddly, and nobody budgets design time for a terminal.
Design decisions
Terminal Kit ships one set of defaults and defends them. Spacing is a four-column baseline grid. Color usage is semantic — success, warning, danger, muted — and maps to the user's own terminal theme rather than hardcoding hex values. Every component degrades gracefully when the terminal reports no color support, because CI logs are a first-class rendering target, not an afterthought.
import { table, spinner } from 'terminal-kit'
const deploy = spinner('Deploying to production')
await release()
deploy.done('Deployed in 34s')
table(services, {
columns: ['name', 'region', 'status'],
status: (s) => s.healthy ? 'ok' : 'danger',
})Maintaining in the open
The project crossed 4,800 stars in its first year. The maintenance philosophy is boring on purpose: small API surface, no plugins until the core is undeniable, every breaking change ships with a codemod. The issue tracker has a label called wontfix-with-love for good ideas that would double the API — it gets used weekly, and people mostly thank us for it.
What it taught me
Open source is a design discipline. Every issue is a usability report from someone who cared enough to write it down. Reading three hundred of them rewired how I name things — the best API name is the one nobody has to ask about.