← Recipes

阅读中文版本

Colorize CLI Output with ANSI Codes

Add ANSI colour to CLI output only when the stream is a terminal and NO_COLOR is unset, respecting user preference.

~20 mincliterminalux

Task

Implement colour that degrades gracefully when output is piped or colour is disabled.

When to use this

A CLI emits colour codes into log files and CI output, cluttering them with escape sequences.

Prerequisites

  • A CLI in any language
  • Access to TTY detection
  • Respect for NO_COLOR convention

Steps

1. Detect a TTY and honour NO_COLOR.

const useColor = process.stdout.isTTY && !process.env.NO_COLOR;
const red = (s) => (useColor ? '\x1b[31m' + s + '\x1b[0m' : s);

Expected output: Colour is applied only on interactive terminals and suppressed when NO_COLOR is set.

2. Verify output is clean when piped.

tool fail | cat -v | grep -c '\^\[' || echo 'no escape codes'

Expected output: Piped output contains no escape sequences, keeping logs and CI clean.

Troubleshooting

Problem

Colour in logs anyway

Solution

Check the actual output file descriptor, not a global flag.

Problem

Colour lost in CI that supports it

Solution

Allow an explicit FORCE_COLOR override for CI where colour is wanted.

Limitations

  • ANSI support varies by terminal.
  • Colour can hurt accessibility; keep semantic labels too.
  • Not a substitute for structured output.

What this recipe does

Implement colour that degrades gracefully when output is piped or colour is disabled.

A CLI emits colour codes into log files and CI output, cluttering them with escape sequences.

Prerequisites

  • A CLI in any language
  • Access to TTY detection
  • Respect for NO_COLOR convention

Procedure

  1. Detect a TTY and honour NO_COLOR.
const useColor = process.stdout.isTTY && !process.env.NO_COLOR;
const red = (s) => (useColor ? '\x1b[31m' + s + '\x1b[0m' : s);

Expected result: Colour is applied only on interactive terminals and suppressed when NO_COLOR is set.

  1. Verify output is clean when piped.
tool fail | cat -v | grep -c '\^\[' || echo 'no escape codes'

Expected result: Piped output contains no escape sequences, keeping logs and CI clean.

How to confirm it worked

Run the commands above and confirm every expected result in order. If a step does not produce the stated output, use the troubleshooting notes before continuing. A passing run shows interactive runs show colour, piped runs contain no escape codes, and NO_COLOR disables colour.

Troubleshooting

Colour in logs anyway — Check the actual output file descriptor, not a global flag.

Colour lost in CI that supports it — Allow an explicit FORCE_COLOR override for CI where colour is wanted.

Limitations

  • ANSI support varies by terminal.
  • Colour can hurt accessibility; keep semantic labels too.
  • Not a substitute for structured output.