Opinionated design-system library for Ink CLIs — pre-styled components and design tokens for a consistent terminal UI.
Features • Quick Start • Components • Tokens • Development
- 🧱 Five ready-made components — Banner, Header, Badge, Spinner, and Table, all pre-styled and immediately usable
- 🎨 Design tokens included — a shared colour palette and spacing scale to keep every screen consistent
- 🟠 Accent-driven style — a warm
#FF8C00accent colour gives your CLI a distinctive, coherent identity - ⚡ ESM only, zero config — ships compiled TypeScript with full type definitions; just import and render
- 🔒 Peer-dep friendly — works with any Ink ≥ 4 and React ≥ 18 setup, no version lock-in
- 🧩 Composable — every component accepts standard Ink primitives so you can mix them with your own layouts freely
- 🏷 Typed throughout — exported types (
BadgeVariant,Column,Color,Spacing) make props self-documenting in any IDE
npm install @kud/ink-uiink and react are peer dependencies — add them if you haven't already:
npm install ink reactimport React from "react"
import { render } from "ink"
import { Banner, Header, Badge, Spinner, Table } from "@kud/ink-ui"
const App = () => (
<>
<Banner title="My CLI" subtitle="v1.0.0" icon="◆" />
<Header subtitle="Fetching packages…">Dependencies</Header>
<Badge variant="success">installed</Badge>
<Badge variant="warning">outdated</Badge>
<Spinner label="Loading…" />
<Table
columns={[
{ key: "name", header: "Package", width: 20 },
{ key: "version", header: "Version", width: 10 },
]}
data={[
{ name: "ink", version: "5.0.0" },
{ name: "react", version: "18.3.1" },
]}
/>
</>
)
render(<App />)Expected output (approximate terminal rendering):
◆ My CLI v1.0.0
Dependencies
Fetching packages…
[installed] [outdated]
⠋ Loading…
Package Version
ink 5.0.0
react 18.3.1
Full-width title block — ideal as an app header at the top of a screen.
| Prop | Type | Default | Description |
|---|---|---|---|
title |
string |
— | Bold title text |
subtitle |
string |
— | Optional dimmed subtitle rendered inline |
icon |
string |
"◆" |
Leading icon rendered in accent colour |
<Banner title="Deploy Tool" subtitle="production" icon="🚀" />Bold, underlined section heading. Use it to separate logical groups within a screen.
| Prop | Type | Default | Description |
|---|---|---|---|
children |
string |
— | The heading text |
subtitle |
string |
— | Optional dimmed subtitle below the heading |
<Header subtitle="3 items">Results</Header>Inline [label] tag with semantic colour variants.
| Prop | Type | Default | Description |
|---|---|---|---|
children |
string |
— | Label text displayed inside brackets |
variant |
BadgeVariant |
"info" |
Colour variant (see table below) |
| Variant | Colour |
|---|---|
success |
green |
error |
red |
warning |
yellow |
info |
cyan |
<Badge variant="error">failed</Badge>Animated dots spinner in accent colour, with an optional dimmed label.
| Prop | Type | Default | Description |
|---|---|---|---|
label |
string |
— | Optional text rendered beside the spinner |
<Spinner label="Building…" />Structured data grid with bold muted column headers. Supports optional fixed column widths and truncates long values cleanly.
| Prop | Type | Description |
|---|---|---|
data |
T[] |
Array of row objects |
columns |
Column<T>[] |
Column definitions (see below) |
Column<T> shape:
| Field | Type | Description |
|---|---|---|
key |
keyof T |
Object key to read for this column |
header |
string |
Column heading text |
width |
number |
Optional fixed character width |
<Table
columns={[
{ key: "name", header: "Name", width: 16 },
{ key: "status", header: "Status" },
]}
data={[
{ name: "api", status: "ok" },
{ name: "db", status: "degraded" },
]}
/>Import colors and spacing to keep your own components aligned with the design system.
import { colors, spacing } from "@kud/ink-ui"| Token | Value | Semantic use |
|---|---|---|
colors.accent |
#FF8C00 |
Primary highlight, icons, spinners |
colors.muted |
gray |
Dimmed text, table headers |
colors.success |
green |
Positive states |
colors.error |
red |
Failures and errors |
colors.warning |
yellow |
Caution states |
colors.info |
cyan |
Neutral informational |
| Token | Value | Description |
|---|---|---|
spacing.xs |
1 |
Tight gap between inline elements |
spacing.sm |
2 |
Small margin between grouped items |
spacing.md |
3 |
Standard section margin |
spacing.lg |
4 |
Large gap between major sections |
ink-ui/
├── src/
│ ├── components/
│ │ ├── Badge.tsx
│ │ ├── Banner.tsx
│ │ ├── Header.tsx
│ │ ├── Spinner.tsx
│ │ └── Table.tsx
│ ├── index.ts # public API
│ └── tokens.ts # colours + spacing
├── dist/ # compiled output (git-ignored)
├── tsconfig.json
└── package.json
| Script | Command | Description |
|---|---|---|
build |
tsc |
Compile TypeScript to dist/ |
dev |
tsc --watch |
Watch mode — recompile on every save |
git clone https://github.com/kud/ink-ui.git
cd ink-ui
npm install
npm run buildTo develop against a local project, link the package:
npm link
cd ../your-project
npm link @kud/ink-ui| Technology | Purpose |
|---|---|
| TypeScript | Strict typing, declaration file output |
| Ink | React renderer for the terminal |
| React | Component model and JSX |
| ink-spinner | Animated spinner primitive |
| ESM | Modern module format, no CommonJS |
MIT © kud — Made with ❤️