Skip to content

Instantly share code, notes, and snippets.

@scop
Last active February 2, 2026 15:20
Show Gist options
  • Select an option

  • Save scop/4d5902b98f0503abec3fcbb00b38aec3 to your computer and use it in GitHub Desktop.

Select an option

Save scop/4d5902b98f0503abec3fcbb00b38aec3 to your computer and use it in GitHub Desktop.
Indicating CLI color preference

This doc is about indicating the preference for color or no color output via environment variables in command line programs. There are some "standards" out there, which many tools luckily support. The support is quirky though.

TL;DR for users

  • To force color: set FORCE_COLOR=1 and CLICOLOR_FORCE=1 (+ unset NO_COLOR if unsure if it might be set).
  • To force no color: set NO_COLOR=1 (+ unset FORCE_COLOR,CLICOLOR_FORCE and CLICOLOR if unsure if they might be set).

The primary use case here is to colorize output of tools in CI, in particular GitHub and GitLab.

Some tools go as far as detecting the CI flavor and doing the right thing (subjective: colorizing) based on their findings, and some tools support more granular color config than just a boolean (but making use of that might throw off some other tools using the same variables (for example specifying a larger number than 1)), etc.

For such tools, the force color recipe here might actually make the output less colorful or "less truecolor" than the tool+env env combo would yield without these variables set as the deeper checks they can do would not be done in presence of these vars. Anyway, I believe it's a net win overall as a rule of thumb for those who don't want to take a deep dive in details.

TL;DR for tool/library authors

Suggested, opinionated and combined check sequence:

  1. If FORCE_COLOR is set to any non-empty value: color is on, look no further.
  2. If command line args and/or config files explicitly turn color on or off: color is on or off respectively, look no further.
  3. If NO_COLOR is set to any non-empty value: color is off, look no further.
  4. If CLICOLOR_FORCE is set to any non-empty value: color is on, look no further.
  5. If CLICOLOR is set to any non-empty value and outputting to a terminal: color is on, look no further.
  6. New programs behave as if CLICOLOR is on, older programs gaining color support have color off by default.

This recipe favors command line arg precedence of FORCE_COLOR/NO_COLOR and ignores that of CLICOLOR_FORCE. Having both is no go as the former is "stronger" (applies to both being turned on or off) and earlier in precedence, so the latter would be redundant (never reached) with it per the algorithm above. It also takes the FORCE_COLOR/NO_COLOR consideration for config files into account.

It also resolves the CLICOLOR_FORCE inconsistencies mentioned below by taking the approach of "on" meaning "set to any non-empty value".

In many cases, for example a library one, checking command line args or config files is not straightforward as it might not be the library's business to do anything with either. (Some libraries in existence do command line arg sniffing though.) But the library could be constructed to take a function as a parameter that returns whether colorizing was explicitly requested on or off in command line args or config files, and plug that function in to its evaluation sequence.

If one does not want to do the whole dance above, I would personally skip the CLICOLOR_FORCE and CLICOLOR steps. The spec for those has seemed more ambiguous and less maintained to me than the two others. Caveat: I don't have numbers how widespread use of each of these vars is. If the CLICOLOR* ones have more substantial "market share" than I guess they do, might want to reconsider.

References

Visited 2025-11-09

Check sequence:

  1. If FORCE_COLOR is on: color is on, look no further.
  2. If command line args and/or config files explicitly turn color on or off: color is on or off respectively, look no further.
  3. If NO_COLOR is on: color is off.

NO_COLOR and FORCE_COLOR are considered on if they're set to any non-empty value.

Check sequence:

  1. If NO_COLOR is on or command line args explicitly turn color off: color is off, look no further.
  2. If CLICOLOR_FORCE is on or command line args explicitly turn color on: color is on, look no further.
  3. If CLICOLOR is on and outputting to a terminal: color is on, look no further.
  4. New programs behave as if CLICOLOR is on, older programs gaining color support have color off by default.

There are inconsistencies in text and example code with regards to set vs set-but-empty, jhasse/clicolors#24.

Config files are not mentioned.

Quirks

There are many, but here's a few.

The Go colorprofile package as of 0.3.3:

The npm supports-color package as of 10.2.2:

CI/CD systems

Many CI/CD systems support color output even if TTYness tests may not return true in them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment