Bring Your CLI to Life with chalk


If you’ve ever littered your Node scripts with raw ANSI escape codes (\x1b[31m
, anyone?) you’ll feel the same relief I did when I stumbled across chalk. This tiny npm package lets you paint text in the terminal with readable, chainable syntax, no magic numbers, no memorizing color codes.
Why bother?
Advantage | What it means in practice |
Readability | chalk.red ('Error') is self-explanatory, future-you will thank present-you. |
Composability | Chain styles: chalk.bold.bgYellow.black (' WARNING ') . |
Context awareness | Chalk detects whether colors are supported (TTY, CI, piping). |
Zero dependencies | Since v5 it’s a single file, no bloat in your installs. |
Typical use-cases
CLI tools & scripts – highlight success, errors, progress bars.
Dev logs – color-code log levels (info, warn, error).
Teaching / demos – emphasize commands or output snippets.
Test runners – brighten up pass / fail summaries.
Quick start
# CommonJS users, stick to chalk v4.x for require()
npm i chalk@4
# or go full ES module with the latest v5
npm i chalk
ES Modules (chalk ≥ 5)
import chalk from 'chalk';
console.log(chalk.green('Server started'));
console.log(chalk.bold.bgRed.white(' 500 ERROR '));
CommonJS (two options)
// a) stay on v4:
const chalk = require('chalk'); // works out of the box
// b) on v5:
const chalk = require('chalk').default; // grab the default export
Handy snippets
// Combine styles
console.log(chalk.bold.underline.cyan('Deployment complete'));
// Nest styles inside template strings
console.log(`
${chalk.green('✔')} Build
${chalk.yellow('→')} Upload
${chalk.red('✖')} Smoke tests
`);
// Dim a whole block
console.log(chalk.dim(`
Hints:
– Press ‘q’ to quit
– Press ‘r’ to reload
`));
Doing it the hard way (native ANSI codes)
Node itself can already print colored text; you just have to embed the escape sequences manually:
// \x1b[31m → red foreground \x1b[0m → reset
console.log('\x1b[31m%s\x1b[0m', 'Error: something went wrong');
// Bold yellow on black background
console.log('\x1b[1m\x1b[43m\x1b[30m WARNING \x1b[0m');
This works, but:
The codes are unreadable and easy to mistype.
You need to handle resets yourself or styles bleed into later output.
There’s no automatic fallback when the terminal doesn’t support color.
Chalk wraps these sequences in clear, chainable functions and handles capability detection for you.
Common pitfalls & how to dodge them
Pitfall | Symptom | Fix |
ESM vs CJS mismatch | Error [ERR_REQUIRE_ESM]… | Use import … from 'chalk' or require('chalk').default ; pin to chalk@4 for full CommonJS. |
Colors missing when piping output | Log file shows no colors | Chalk disables color in non-TTY; force it with chalk.level = 1 or env CHALK_LEVEL=1 . |
Nested chalk resets | Styles bleed into lines | Keep everything inside one chalk chain; don’t mix raw ANSI codes and chalk in the same string. |
True-color not detected | Only 16 colors available | Upgrade your terminal or set chalk.level = 3 if your terminal really supports 24-bit color. |
Final thoughts
Chalk won’t magically fix bad logs, but it does turn a wall of monochrome text into something your eyes can parse in seconds. Set the level once, pick the right version for your module system, and you’ll never write raw ANSI codes again.
Subscribe to my newsletter
Read articles from Amir Yurista directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
