Skip to content

FORCE_COLOR=0 enables colors instead of disabling them #100

@FrozenPandaz

Description

@FrozenPandaz

Summary

FORCE_COLOR=0 is treated as "enable colors" by picocolors, when it should mean "disable colors." This is inconsistent with the behavior of chalk and the FORCE_COLOR spec.

Current Behavior

// FORCE_COLOR=0 node test.js
const pc = require('picocolors');
console.log(pc.isColorSupported); // true
console.log(JSON.stringify(pc.green('hello'))); // "\u001b[32mhello\u001b[39m"

Colors are enabled because the detection logic uses !!env.FORCE_COLOR, and !!"0" is true in JavaScript:

let isColorSupported =
  !(!!env.NO_COLOR || argv.includes("--no-color")) &&
  (!!env.FORCE_COLOR || argv.includes("--color") || ...)
//  ^^^^^^^^^^^^^^^^ "0" is truthy

Expected Behavior

FORCE_COLOR=0 should disable colors, matching chalk's behavior:

// chalk with FORCE_COLOR=0
const chalk = require('chalk');
console.log(chalk.level); // 0
console.log(JSON.stringify(chalk.green('hello'))); // "hello" (no ANSI codes)

Per the FORCE_COLOR spec:

  • FORCE_COLOR=0 → disable colors
  • FORCE_COLOR=1 → enable basic colors
  • FORCE_COLOR=2 → enable 256 colors
  • FORCE_COLOR=3 → enable truecolor

Suggested Fix

Check the value of FORCE_COLOR rather than just its existence:

let isColorSupported =
  !(!!env.NO_COLOR || argv.includes("--no-color")) &&
  (env.FORCE_COLOR !== '0') &&
  ((env.FORCE_COLOR && env.FORCE_COLOR !== '') || argv.includes("--color") || p.platform === "win32" || ((p.stdout || {}).isTTY && env.TERM !== "dumb") || !!env.CI)

Impact

This is a behavioral difference from chalk that causes regressions when projects migrate from chalk to picocolors. For example, CI environments and tools like Homebrew set FORCE_COLOR=0 to get parseable plain text output, and this breaks after migration.

Environment

  • picocolors v1.1.1
  • Node.js v22+

Note: The fix in v1.1.1 (#87) addressed empty strings in FORCE_COLOR/NO_COLOR, but did not address the FORCE_COLOR=0 case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions