colors.js
Terminal string styling for Node.js console output, and the package at the center of a 2022 supply-chain sabotage incident.
Repository Health
Technical Analysis
colors.js adds ANSI colors and text styles to strings printed to a Node.js console, either by extending String.prototype ('hello'.green) or through a non-mutating colors/safe API (colors.red('hello')). It ships built-in foreground/background color palettes, text style modifiers (bold, underline, inverse, strikethrough), a setTheme() API for mapping semantic log levels (error, warn, info) to styles, and TTY-aware auto-detection that disables color codes when output isn’t a terminal or NO_COLOR/--no-color is set.
The project is also the subject of a well-documented 2022 supply-chain incident: its maintainer intentionally published corrupted versions (1.4.1 and later 1.4.44-liberty-2, the “Liberty Loop”) that printed a broken American-flag banner and looped infinitely, breaking thousands of downstream projects that had loosely pinned to ^1.4.0. npm reverted the registry’s latest tag to the last clean release, 1.4.0, which is what installs by default today — but the GitHub repository’s default branch still contains the sabotage code, so cloning or installing directly from GitHub (rather than npm) pulls in the infinite-loop payload.
What You Get
- Sixteen foreground/background color styles (standard + bright variants), applied via String.prototype or the safe API
- Text style modifiers: bold, dim, italic, underline, inverse, hidden, strikethrough, reset
- A
setTheme()API for mapping semantic log-level names (error, warn, info, debug) to color styles - TTY-aware color support detection (
supports-colors/has-flag) that disables ANSI codes automatically in non-interactive environments or whenNO_COLOR/--no-coloris set - Novelty character-level effects:
rainbow,zebra,trap,zalgo, andamerica
Common Use Cases
- Coloring CLI tool output (errors in red, warnings in yellow, success in green) for readability in a terminal
- Building simple theme-based logging conventions in Node.js scripts via
colors.setTheme() - Adding ANSI styling to build/test script output without pulling in a heavier formatting framework
- Auditing a project’s lockfile for a pinned
colors@1.4.0to avoid accidentally resolving the sabotaged 1.4.1/1.4.44 releases
Under The Hood
Architecture
colors.js is a small, flat CommonJS module with no build step: lib/index.js requires lib/colors.js (which defines the core colors object, ANSI style table, and setTheme/extend/strip methods via Object.defineProperties) and then calls require('./extendStringPrototype')() to mirror those same properties onto String.prototype, giving the fluent 'text'.red syntax; colors/safe.js re-exports the same lib/colors.js object without the prototype-extension step for callers who don’t want to mutate String. Color-support detection is isolated in lib/system/supports-colors.js/has-flag.js (adapted from chalk’s supports-color), and the playful extras (rainbow, zebra, trap, zalgo, america) live as separate modules under lib/maps/ and lib/custom/, each implementing a per-character or per-line ANSI transform. Critically, this repository’s cloned default branch still contains the literal sabotage payload from the January 2022 incident directly inside lib/index.js — an infinite for loop combined with a call into lib/custom/american.js, both left in place under a comment reading /* remove this line after testing */ — meaning a plain require('colors') against this exact ref hangs and spams garbled console output rather than loading normally.
Tech Stack
The library has zero runtime dependencies and targets any Node.js >=0.1.90; the only devDependencies are eslint and eslint-config-google for linting (.eslintrc.json extends google with a few rules disabled). There is no bundler, transpiler, or TypeScript compiler — index.d.ts and safe.d.ts are hand-written ambient type declarations shipped alongside plain JavaScript. CI is configured via a .travis.yml (Travis CI, effectively defunct as a free service today), and the package is distributed on npm under the name colors with lib/index.js as main.
Code Quality
Testing is minimal: tests/basic-test.js and tests/safe-test.js are flat scripts run directly with node (npm test) using only Node’s built-in assert module — there is no test framework, no coverage tooling, and no CI status that can be trusted given Travis’s decommissioning. Naming and style are otherwise consistent and ESLint-enforced, but code quality here has to be read through the lens of the project’s history: package.json’s own version field reads 1.4.44-liberty-2, a non-semver string reflecting the maintainer’s self-described “Liberty Loop” protest, and the repository’s default branch still ships the actual sabotage code — the infinite loop and American-flag banner from the widely reported January 2022 incident — sitting live in the require path of lib/index.js. This is not a hypothetical risk; it is the exact code that broke thousands of downstream builds when it shipped as 1.4.1/1.4.44-liberty-2 on npm. npm has since reverted the registry’s latest tag to the last clean release, 1.4.0, which is what a normal npm install colors resolves to today, but installing directly from GitHub’s default branch does not get that protection.
API Design
colors.js popularized two now-common ergonomic patterns in Node.js terminal styling: fluent property-chaining directly on strings ('text'.red.bold) and, for callers wary of mutating built-ins, an equivalent function-call API via require('colors/safe') (colors.red.bold('text')). It also added setTheme() for mapping arbitrary semantic keys to style chains, letting callers write console.log('this is an error'.error) after registering error: 'red'. These ideas were influential in the era (predating and partly motivating alternatives like chalk, which explicitly avoided String.prototype extension), but the pattern is now widely considered an anti-pattern for library code because it pollutes a shared global. Combined with the unmaintained state (last real commit mid-2023) and the 2022 sabotage incident, the API-design story here is now inseparable from its role as a cautionary supply-chain example rather than a recommendation for new projects — most teams today reach for chalk, picocolors, or kleur instead.
Used by 7 apps in this directory
CodeSandbox
Code Editors · Developer Tools
Instantly ready browser-based IDE that runs full npm dependency resolution and transpilation entirely client-side, with no server needed.
Countly
Analytics · Marketing
Privacy-first, self-hosted analytics and customer engagement platform with full data ownership, GDPR compliance, and AI-powered insights across mobile, web, desktop, and IoT.
Flagsmith
Developer Tools · Devops · Ab Testing Experimentation
Open-source feature flagging, remote config, and A/B/multivariate testing platform for web, mobile, and server-side apps — self-host or use the hosted SaaS.
GraphQL Hive
Developer Tools · Devops · Monitoring
Open-source GraphQL schema registry and observability platform with breaking change detection, federation support, and CI/CD integration for teams of any size.
NocoDB
No Code Platforms · Databases · Low Code Platforms
Turn any SQL database into a collaborative no-code spreadsheet with automatic REST APIs and real-time views.
Rocket.Chat
Team Chat
The secure, self-hosted team communications platform for organizations that cannot compromise on data sovereignty.
Social Analyzer
Security
Find and analyze a person's digital footprint across 1000+ social media platforms using multi-layer detection, OCR, and metadata extraction.