BeautifulCLITerminal string styling done right — a chainable, zero-dependency library for adding color and style to Node.js CLI output.
Guide

Modifiers

All text-modifier style names with type signatures and behavior notes (e.g. visible suppresses output when color is disabled).


Overview

Modifiers are style properties that change how text appears in the terminal without affecting its color — think of them as text decoration. Chalk exposes ten modifiers (reset, bold, dim, italic, underline, overline, inverse, hidden, strikethrough, and visible) as chainable properties on the main chalk object, so you can stack them with colors and backgrounds in a single expression. Understanding each modifier's behavior — especially visible, which silences output when color is disabled — helps you build CLI output that is both expressive and safe across every environment Chalk supports.


Prerequisites

Before using Chalk modifiers, make sure you have the following in place:

  • Node.js 16 or later — required by Chalk 5
  • ESM module system — Chalk 5 is ESM-only; require('chalk') throws a runtime error. If you are on a CommonJS project that cannot migrate to ESM, pin to chalk@4 instead.
  • Chalk installed — see the Installation section below
  • A color-capable terminal — several modifiers (italic, underline, overline, strikethrough) are not widely supported across all terminal emulators; test in your target environment
  • TypeScript (optional) — Chalk ships type definitions; no separate @types package is needed

Installation
  1. Install Chalk from the npm registry:
npm install chalk

Or with yarn:

yarn add chalk

Or with pnpm:

pnpm add chalk
  1. Import the default export in your ESM module:
import chalk from 'chalk';

Chalk has zero runtime dependencies, so nothing extra is pulled in.


Configuration

Chalk reads terminal color support automatically, but you can control it when the auto-detected level is not what you want.

chalk.level

A read/write property on any Chalk instance that sets how many colors are available.

ValueConstant nameEffect
0DisabledAll ANSI codes are stripped; modifiers produce plain text (see visible below)
1Basic16-color palette; true-color and 256-color values are downsampled
2256-color256 indexed colors; true-color values are downsampled
3TruecolorFull 16-million-color support

Setting chalk.level globally affects every caller in the same process. If you are writing a library, create an isolated instance instead so you do not override the consumer's preference:

import { Chalk } from 'chalk';

const customChalk = new Chalk({ level: 0 }); // modifiers disabled for this instance

Environment variable overrides

You can force a color level from outside the process without changing any code:

FORCE_COLOR=0 node my-script.js   # disable all color
FORCE_COLOR=1 node my-script.js   # force basic 16 colors
FORCE_COLOR=2 node my-script.js   # force 256 colors
FORCE_COLOR=3 node my-script.js   # force Truecolor

FORCE_COLOR overrides all other detection logic, including --color / --no-color flags. This is useful in CI pipelines where terminal detection may report level 0.

modifierNames export

Chalk exports the full list of modifier names as a readonly string array, which is convenient for input validation:

import { modifierNames } from 'chalk';

console.log(modifierNames);
// => ['reset','bold','dim','italic','underline','overline','inverse','hidden','strikethrough','visible']

Usage

Every modifier is a chainable property on the chalk object. You access it as a getter, chain additional styles, and then call the final result as a function with one or more strings:

chalk.<modifier>('text')
chalk.<modifier>.<color>('text')
chalk.<color>.<modifier>.<modifier>('text')

Order within the chain does not matter for most modifiers — chalk.bold.red and chalk.red.bold produce the same output. When two conflicting styles are present (for example, two different foreground colors), the last one in the chain wins.

Modifier reference

PropertyType signatureBehavior
resetreadonly thisResets all active styles back to the terminal default
boldreadonly thisIncreases font weight
dimreadonly thisRenders the text at lower opacity
italicreadonly thisRenders the text in italic (not widely supported)
underlinereadonly thisDraws a horizontal line below the text (not widely supported)
overlinereadonly thisDraws a horizontal line above the text (not widely supported)
inversereadonly thisSwaps the foreground and background colors
hiddenreadonly thisRenders the text invisible (characters still occupy space)
strikethroughreadonly thisDraws a horizontal line through the center of the text (not widely supported)
visiblereadonly thisRenders the text only when chalk.level > 0; produces an empty string when color is disabled

The visible modifier in detail

visible is the most behaviorally distinct modifier. Unlike the others, it does not add a visual decoration — instead it acts as a gate on output:

  • When chalk.level >= 1, chalk.visible('text') returns 'text' (with any other chained styles applied).
  • When chalk.level === 0, chalk.visible('text') returns ''.

This makes visible ideal for purely cosmetic output — spinner characters, decorative separators, progress bars — that should vanish entirely in plain-text environments rather than appearing as unstyled clutter.

Chaining modifiers with colors

Modifiers compose freely with color and background methods:

import chalk from 'chalk';

// Modifiers alone
console.log(chalk.bold('Important'));
console.log(chalk.dim('De-emphasized'));

// Modifiers combined with colors
console.log(chalk.red.bold.underline('Error'));

// Nested styles restore the outer style automatically
console.log(chalk.green('OK: ' + chalk.bold('all systems go')));

Using modifiers inside reusable theme objects

Because chained Chalk expressions return a new ChalkInstance, you can assign them to variables and reuse them throughout your application:

import chalk from 'chalk';

const heading = chalk.bold.underline;
const subtle  = chalk.dim;
const danger  = chalk.red.bold;

console.log(heading('Section title'));
console.log(subtle('(internal note)'));
console.log(danger('Fatal error'));

Examples

1. bold — emphasize critical output

import chalk from 'chalk';

console.log(chalk.bold('Build succeeded'));

Expected terminal output: Build succeeded rendered in bold weight.


2. dim — de-emphasize secondary information

import chalk from 'chalk';

console.log(chalk.green('✔ Done') + ' ' + chalk.dim('(3 files written)'));

Expected terminal output: A bright green checkmark and label, followed by a faded annotation.


3. underline — draw attention to a label

import chalk from 'chalk';

console.log(chalk.underline('WARNINGS'));

Expected terminal output: WARNINGS with a line beneath it. (Not widely supported — verify in your target terminal.)


4. italic — add emphasis

import chalk from 'chalk';

console.log(chalk.italic('Tip: run with --verbose for more detail'));

Expected terminal output: The tip string in italic style. (Not widely supported — verify in your target terminal.)


5. strikethrough — mark deprecated items

import chalk from 'chalk';

console.log(chalk.strikethrough('--legacy-flag') + '  (removed in v3)');

Expected terminal output: --legacy-flag with a horizontal line through it, followed by a plain note. (Not widely supported.)


6. inverse — highlight a selected item in a menu

import chalk from 'chalk';

const options = ['Start', 'Configure', 'Exit'];
const selectedIndex = 1;

for (const [i, option] of options.entries()) {
  const line = i === selectedIndex ? chalk.inverse(option) : option;
  console.log(line);
}

Expected terminal output:

Start
[Configure]   ← foreground and background colors swapped
Exit

7. hidden — embed invisible text

import chalk from 'chalk';

console.log('Visible text ' + chalk.hidden('secret') + ' more visible text');

Expected terminal output: Both visible strings appear; secret occupies space but is not visible. Selecting the text in many terminals will reveal it.


8. overline — place a line above the text

import chalk from 'chalk';

console.log(chalk.overline('Report Summary'));

Expected terminal output: Report Summary with a line drawn above it. (Not widely supported — supported on VTE-based terminals, GNOME Terminal, mintty, and Git Bash.)


9. reset — clear all active styles mid-chain

import chalk from 'chalk';

console.log(chalk.red.bold('Error: ' + chalk.reset('details here')));

Expected terminal output: Error: in red bold, then details here in the terminal's default style.


10. visible — suppress cosmetic output when color is disabled

import { Chalk } from 'chalk';

const plain  = new Chalk({ level: 0 });
const styled = new Chalk({ level: 3 });

console.log(JSON.stringify(plain.visible('spinner')));   // => ""
console.log(JSON.stringify(styled.visible('spinner')));  // => "spinner"

Expected output:

""
"spinner"

visible produces an empty string when the color level is 0, so decorative output disappears automatically in CI or plain-text log contexts.


11. Chaining multiple modifiers with a color

import chalk from 'chalk';

console.log(chalk.yellow.bold.underline('WARNING: disk usage above 90%'));

Expected terminal output: The warning string in yellow, bold, and underlined simultaneously.


12. Introspecting available modifier names at runtime

import { modifierNames } from 'chalk';

function applyModifier(mod, text) {
  if (!modifierNames.includes(mod)) {
    throw new Error(`Unknown modifier: ${mod}`);
  }

  // ... apply dynamically
}

console.log(modifierNames.includes('bold'));  // true
console.log(modifierNames.includes('pink'));  // false

Troubleshooting

Modifier has no visible effect

Symptom: Calling chalk.bold('text') or chalk.underline('text') prints plain text with no styling.

Likely cause: chalk.level is 0, either because the terminal reported no color support or FORCE_COLOR=0 is set.

Fix: Check the detected level and override if appropriate:

import chalk from 'chalk';

console.log(chalk.level); // 0 means color is disabled

To force styling on:

FORCE_COLOR=1 node your-script.js

Or in code (only do this in application code, not in libraries):

chalk.level = 1;

italic, underline, overline, or strikethrough are not rendered

Symptom: The modifier appears to do nothing even though chalk.level is above 0.

Likely cause: These four modifiers are not widely supported. Many terminals, including older versions of Windows cmd.exe and some SSH clients, do not implement the corresponding ANSI sequences.

Fix: Test in a modern terminal emulator. On Windows, use Windows Terminal. On macOS and Linux, iTerm2, GNOME Terminal, Kitty, and Alacritty support all four. Do not rely on these modifiers for conveying critical information — pair them with a color as a fallback.


visible produces an empty string unexpectedly

Symptom: Output that should appear is silently dropped.

Likely cause: chalk.level is 0. The visible modifier intentionally suppresses output when color support is disabled.

Fix: visible is designed for purely cosmetic strings. If the string must always appear, remove visible from the chain and use chalk.reset or a plain string instead. If you need to debug the level:

import chalk from 'chalk';

console.log('Color level:', chalk.level);
console.log(chalk.visible('this is cosmetic'));

require('chalk') throws at runtime

Symptom: Error [ERR_REQUIRE_ESM]: require() of ES Module ... not supported

Likely cause: Chalk 5 is ESM-only. Using require() in a CommonJS project will always throw.

Fix: Either migrate your project to ESM (add "type": "module" to package.json and use import), or pin to Chalk 4 which supports CommonJS:

npm install chalk@4

Styles from a custom Chalk instance bleed into the main chalk object

Symptom: Changing level on one instance affects output from a different part of the codebase.

Likely cause: You modified chalk.level on the shared default export rather than creating a separate instance.

Fix: Use new Chalk({ level }) from the named export to create an isolated instance whose level is independent of the global default:

import { Chalk } from 'chalk';

const testChalk = new Chalk({ level: 0 });
// testChalk.level === 0; the default chalk export is unaffected