Chalk Picocolors
Style terminal output with chalk and picocolors for colored, formatted CLI text
You are an expert in styling terminal output using chalk and picocolors for building visually clear CLI applications.
## Key Points
- Choose picocolors for libraries and tools where minimal dependencies matter; choose chalk when you need hex colors (`chalk.hex('#ff6600')`), RGB values, or color-level control.
- Always define semantic color functions (`log.success`, `log.error`) rather than scattering raw `chalk.green()`/`chalk.red()` calls throughout code — this makes theme changes trivial.
- Respect the `NO_COLOR` standard (https://no-color.org/) — both chalk v5+ and picocolors handle this automatically, but verify if wrapping them.
- **Using chalk v5 in a CommonJS project without migration** — chalk v5 is ESM-only and will fail with `require()`; either use chalk v4, switch to picocolors, or migrate the project to ESM.
- **Over-coloring output** — applying colors to every word makes the terminal look like a rainbow and reduces the signal-to-noise ratio; use color sparingly to highlight important information.
- Chalk v5 is ESM-only — if your project uses CommonJS (`require`), either use chalk v4 (`npm install chalk@4`) or switch your project to ESM with `"type": "module"` in `package.json`.
## Quick Example
```bash
# Full-featured option
npm install chalk
# Lightweight option
npm install picocolors
```
```ts
import pc from 'picocolors';
console.log(pc.green('Success!'));
console.log(pc.red(pc.bold('Error: something went wrong')));
console.log(pc.blue(pc.underline('https://example.com')));
```skilldb get cli-development-skills/Chalk PicocolorsFull skill: 168 linesTerminal Styling (chalk, picocolors) — CLI Development
You are an expert in styling terminal output using chalk and picocolors for building visually clear CLI applications.
Overview
Terminal styling libraries add colors, bold/dim/underline formatting, and background colors to CLI output. Chalk is the most popular and feature-rich option. Picocolors is a minimal, zero-dependency alternative that is 14x smaller and 2x faster — ideal when bundle size matters (e.g., libraries and dev tools).
Setup & Configuration
Install either library:
# Full-featured option
npm install chalk
# Lightweight option
npm install picocolors
Basic usage with chalk:
import chalk from 'chalk';
console.log(chalk.green('Success!'));
console.log(chalk.red.bold('Error: something went wrong'));
console.log(chalk.blue.underline('https://example.com'));
console.log(chalk.bgYellow.black(' WARNING ') + ' Check your config');
Basic usage with picocolors:
import pc from 'picocolors';
console.log(pc.green('Success!'));
console.log(pc.red(pc.bold('Error: something went wrong')));
console.log(pc.blue(pc.underline('https://example.com')));
Core Patterns
Semantic color helpers
import chalk from 'chalk';
const log = {
info: (msg: string) => console.log(chalk.blue('ℹ') + ' ' + msg),
success: (msg: string) => console.log(chalk.green('✔') + ' ' + msg),
warn: (msg: string) => console.log(chalk.yellow('⚠') + ' ' + chalk.yellow(msg)),
error: (msg: string) => console.log(chalk.red('✖') + ' ' + chalk.red(msg)),
dim: (msg: string) => console.log(chalk.dim(msg)),
};
log.success('Build completed in 1.2s');
log.warn('Deprecated API usage detected');
log.error('Failed to connect to database');
Template literals with chalk
import chalk from 'chalk';
const name = 'my-app';
const version = '2.1.0';
const env = 'production';
console.log(`
${chalk.bold(name)} ${chalk.dim(`v${version}`)}
${chalk.gray('Environment:')} ${chalk.cyan(env)}
${chalk.gray('Status:')} ${chalk.green('running')}
`);
Conditional coloring
import chalk from 'chalk';
function statusColor(status: string): string {
switch (status) {
case 'pass': return chalk.green(status);
case 'fail': return chalk.red(status);
case 'skip': return chalk.yellow(status);
default: return chalk.gray(status);
}
}
function severityBadge(level: string): string {
const badges: Record<string, string> = {
critical: chalk.bgRed.white(` ${level.toUpperCase()} `),
warning: chalk.bgYellow.black(` ${level.toUpperCase()} `),
info: chalk.bgBlue.white(` ${level.toUpperCase()} `),
};
return badges[level] ?? level;
}
Respecting NO_COLOR and color detection
import chalk from 'chalk';
// chalk v5+ auto-detects NO_COLOR, FORCE_COLOR, and terminal capability
// You can also control it manually:
const c = new chalk.Instance({ level: process.env.NO_COLOR ? 0 : undefined });
console.log(c.green('This respects NO_COLOR'));
// picocolors also auto-detects NO_COLOR
import pc from 'picocolors';
// No configuration needed — it just works
Using picocolors as a chalk drop-in for simple cases
import pc from 'picocolors';
// picocolors uses nesting instead of chaining
console.log(pc.bold(pc.red('Error'))); // chalk: chalk.red.bold('Error')
console.log(pc.dim(pc.green('done'))); // chalk: chalk.green.dim('done')
// It covers all common formatters:
// pc.red, pc.green, pc.blue, pc.yellow, pc.cyan, pc.magenta, pc.white, pc.gray
// pc.bold, pc.dim, pc.underline, pc.italic, pc.strikethrough, pc.inverse
// pc.bgRed, pc.bgGreen, pc.bgBlue, pc.bgYellow, pc.bgCyan, pc.bgMagenta
Best Practices
- Choose picocolors for libraries and tools where minimal dependencies matter; choose chalk when you need hex colors (
chalk.hex('#ff6600')), RGB values, or color-level control. - Always define semantic color functions (
log.success,log.error) rather than scattering rawchalk.green()/chalk.red()calls throughout code — this makes theme changes trivial. - Respect the
NO_COLORstandard (https://no-color.org/) — both chalk v5+ and picocolors handle this automatically, but verify if wrapping them.
Core Philosophy
Color in a CLI is not decoration — it is information architecture. A red message means something failed, a green checkmark means success, and dim text signals secondary information. Establish semantic color functions early and use them consistently so that users can scan output at a glance without reading every word. Raw chalk.green() scattered throughout the codebase makes color choices invisible and theme changes impossible.
Respect the terminal environment. Not every terminal supports 16 million colors, and not every user wants color at all. The NO_COLOR standard exists because some users pipe output to files, run in CI, or have accessibility needs that color interferes with. Both chalk and picocolors handle this automatically, but if you wrap them, verify that your wrapper degrades gracefully when color is disabled.
Choose the right tool for the job. Picocolors is 14x smaller than chalk and covers 95% of use cases. Unless you need hex colors, RGB values, or fine-grained color level control, picocolors is the better default — especially for libraries and dev tools where dependency weight matters to your users.
Anti-Patterns
-
Scattering raw color calls throughout business logic — calling
chalk.red()directly in dozens of files makes it impossible to change the color scheme or add theme support; define semantic helpers likelog.error()andlog.success()in one place. -
Ignoring the
NO_COLORenvironment variable — hardcoding color output or overriding detection breaks accessibility and produces unreadable ANSI escape sequences in logs, CI output, and piped files. -
Using chalk v5 in a CommonJS project without migration — chalk v5 is ESM-only and will fail with
require(); either use chalk v4, switch to picocolors, or migrate the project to ESM. -
Over-coloring output — applying colors to every word makes the terminal look like a rainbow and reduces the signal-to-noise ratio; use color sparingly to highlight important information.
-
Logging styled strings to files without stripping ANSI — writing
chalk.green('success')to a log file produces\x1b[32msuccess\x1b[39mgarbage; strip colors before file output or setchalk.level = 0for file loggers.
Common Pitfalls
- Chalk v5 is ESM-only — if your project uses CommonJS (
require), either use chalk v4 (npm install chalk@4) or switch your project to ESM with"type": "module"inpackage.json. - Logging styled strings to files produces ANSI escape codes (e.g.,
\x1b[32m) — strip colors before writing to files or piping output by settingchalk.level = 0or using a library likestrip-ansi.
Install this skill directly: skilldb add cli-development-skills
Related Skills
Clack Prompts
Build beautiful interactive CLI prompts using @clack/prompts with minimal boilerplate
CLI Distribution
Package and distribute CLI tools via npm/npx, standalone binaries with pkg, and Homebrew taps
CLI Testing
Test CLI applications using subprocess execution, mock filesystems, and snapshot testing
Commander Js
Build structured CLI applications with Commander.js including commands, options, and argument parsing
Ink React CLI
Build rich interactive terminal UIs using Ink, a React renderer for the command line
Oclif Framework
Build production-grade, extensible CLI tools using the oclif framework with TypeScript