Skip to main content
Technology & EngineeringCli Development168 lines

Chalk Picocolors

Style terminal output with chalk and picocolors for colored, formatted CLI text

Quick Summary30 lines
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 lines
Paste into your CLAUDE.md or agent config

Terminal 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 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.

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 like log.error() and log.success() in one place.

  • Ignoring the NO_COLOR environment 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[39m garbage; strip colors before file output or set chalk.level = 0 for 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" in package.json.
  • Logging styled strings to files produces ANSI escape codes (e.g., \x1b[32m) — strip colors before writing to files or piping output by setting chalk.level = 0 or using a library like strip-ansi.

Install this skill directly: skilldb add cli-development-skills

Get CLI access →