Composable CLI color and layout toolkit: beautiful boxes, banners, tables, gradients, and more.
A modern, fast, and expressive Node.js CLI styling & layout library for the next generation of command-line tools. Easily style text, draw boxes, banners, tables, progress bars, and more—with first-class TypeScript support and a clean, composable API.
pnpm add @chromakit/core
# Or
yarn add @chromakit/core
# Or
npm install @chromakit/core
import { color, gradient } from 'chromakit/color';
import { bold, underline, dim, composeStyles } from 'chromakit/style';
console.log(color('Hello', 'magenta'));
console.log(gradient('Rainbow!', ['red', 'yellow', 'green', 'blue']));
console.log(bold(underline('Elite Output')));
console.log(composeStyles([bold, dim])('Elite + Dim'));
import { banner } from 'chromakit/layout/banner';
import { box } from 'chromakit/layout/box';
console.log(banner('🚀 ChromaKit Rocks!', { color: 'cyan', char: '~', spacing: true }));
console.log(
box(['ChromaKit', 'Box example'], { title: 'Test', borderStyle: 'single', borderColor: 'cyan' }),
);
import { divider } from 'chromakit/layout/divider';
console.log(divider({ color: 'green', char: '=', width: 50 }));
import { table } from 'chromakit/layout/table';
console.log(
table(
[
['foo', 42, 'bar'],
['baz', 3, 'qux'],
],
{
headers: ['Name', 'Value', 'Type'],
align: ['left', 'right', 'center'],
borderColor: 'blue',
headerStyle: bold,
cellStyle: (cell, row, col) => (col === 1 ? color(cell, 'yellow') : cell),
padding: 1,
},
),
);
import { progressBar } from 'chromakit/layout/progress-bar';
console.log(progressBar(0.42, { width: 30, color: 'cyan', showPercent: true, border: true }));
import { withProgressBar } from 'chromakit/animation/progress-animate';
import { withMultiStepProgress } from 'chromakit/animation/progress-multistep';
// Single-bar animation
await withProgressBar(
async (update) => {
for (let i = 0; i <= 100; ++i) {
await sleep(18); // custom sleep util
update(i / 100, `Progress: ${i}%`);
}
},
{ color: 'cyan', border: true },
);
// Multi-step progress (serial)
await withMultiStepProgress(
[
{
label: 'Install',
fn: async (update) => {
for (let i = 0; i < 20; ++i) {
await sleep(20);
update?.(i / 20);
}
},
},
{
label: 'Build',
fn: async (update) => {
for (let i = 0; i < 24; ++i) {
await sleep(15);
update?.(i / 24);
}
},
},
{
label: 'Deploy',
fn: async (update) => {
for (let i = 0; i < 8; ++i) {
await sleep(45);
update?.(i / 8);
}
},
},
],
{ color: 'green', border: true },
);
import { multiProgress } from 'chromakit/animation/progress-concurrent';
const mp = multiProgress([
{ label: 'Download A', progress: 0, opts: { color: 'yellow' } },
{ label: 'Download B', progress: 0, opts: { color: 'magenta' } },
{ label: 'Download C', progress: 0, opts: { color: 'blue' } },
]);
for (let i = 0; i <= 100; i++) {
mp.update(0, i / 100, `A: ${i}%`);
mp.update(1, Math.min(i / 100 + 0.18, 1), `B: ${Math.round(Math.min(i + 18, 100))}%`);
mp.update(2, Math.max(0, (i - 16) / 80), `C: ${Math.round(Math.max(0, i - 16))}%`);
await sleep(13);
}
mp.stop('✅ All parallel jobs done!');
import { startSpinner } from 'chromakit/animation/spinner';
const spinner = startSpinner('Loading awesome...');
await sleep(1000);
spinner.update('Almost done!');
await sleep(500);
spinner.stop('All done!');