@mpen/ansi-colors
v0.3.0
Published

Readme

@mpen/ansi-colors
Small, composable ANSI formatters for Node.js, Bun, and other JavaScript environments. The main entry point exposes each formatter independently so bundlers can remove unused colors.
Installation
bun add @mpen/ansi-colorsUsage
Import the package as a namespace for a concise API:
import * as ac from '@mpen/ansi-colors'
console.log(ac.green('Success!'))
console.log(ac.bold(ac.red('Error: Access denied.')))Named imports work well when bundle size matters. Each formatter is an independent export, so an ESM bundler can retain only the functions that are used:
import { bold, red } from '@mpen/ansi-colors'
console.log(bold(red('Error')))Truecolor
rgb, bgRgb, hex, and bgHex create reusable 24-bit color formatters:
import * as ac from '@mpen/ansi-colors'
const purple = ac.hex('#7c3aed')
const bgGold = ac.bgHex('ffd700')
const orange = ac.rgb(255, 128, 0)
console.log(purple(bgGold(' Royal and Gold ')))
console.log(orange('Warning'))RGB channels must be integers from 0 through 255. Hex colors may contain three or six digits, with an optional # prefix.
Explicitly enabling or disabling colors
The root exports automatically detect color support. Use the opt-in class entry point when support must be overridden:
import { AnsiColors } from '@mpen/ansi-colors/class'
const ac = new AnsiColors(false)
console.log(ac.red('This remains plain text.'))new AnsiColors() uses automatic detection. Pass false for level 0, true for level 3, or a ColorLevel value explicitly. The constructor accepts one argument. The instance exposes colorSupportLevel; its boolean support properties are deprecated. RGB and hex formatters continue to emit 24-bit sequences when enabled; they do not quantize to a lower palette. The class contains the complete formatter collection and therefore is not intended to be tree-shaken per method.
Color support detection
Automatic detection considers NO_COLOR, FORCE_COLOR, CI, TERM, TTY status, and the Windows platform. The detected result is exported as colorSupportLevel: ColorLevel.None (0), ColorLevel.Basic (1), ColorLevel.Ansi256 (2), or ColorLevel.TrueColor (3). TERM values ending in -256color or -256, Apple Terminal, and FORCE_COLOR=2 identify 256-color support. The old isColorSupported and isTrueColorSupported booleans are deprecated.
API
| Category | Exports |
| :----------------- | :------------------------------------------------------------------------------------------------------------------------------------ |
| Modifiers | reset, bold, dim, italic, underline, inverse, hidden, strikethrough |
| Text colors | black, red, green, yellow, blue, magenta, cyan, white, gray |
| Bright text | blackBright, redBright, greenBright, yellowBright, blueBright, magentaBright, cyanBright, whiteBright |
| Backgrounds | bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite |
| Bright backgrounds | bgBlackBright, bgRedBright, bgGreenBright, bgYellowBright, bgBlueBright, bgMagentaBright, bgCyanBright, bgWhiteBright |
| Custom colors | rgb, bgRgb, hex, bgHex |
| Hyperlinks | link |
Comparison
How @mpen/ansi-colors compares to popular alternatives and the built-in Node.js utility:
| Feature | @mpen/ansi-colors | ansis | picocolors | chalk | util.styleText |
| :------------------------------- | :------------------------------------------------------ | :----------------------------------------------- | :----------------------------------------------------------- | :---------------------------------------------------------- | :------------------------------------------------------------------------------------ |
| Type | Package (ESM) | Package (ESM/CJS) | Package (CJS) | Package (ESM) | Built-in (Node.js runtime) |
| API style | Functional (bold(red(x))) | Chained & templates (red.bold`x`) | Functional (pico.red(pico.bold(x))) | Chained & templates (chalk.red.bold(x)) | Formatter argument (styleText(['bold', 'red'], x)) |
| Tree-shakeable | Yes (pure per-export functions) | No (monolithic CJS core & chained instances) | No (single object of all formatters) | No (monolithic builder & prototype chain) | N/A (built-in; non-portable outside Node) |
| Standard colors & modifiers | Yes (16 colors + 8 modifiers) | Yes | Yes | Yes | Yes |
| Truecolor (24-bit RGB / Hex) | Yes (rgb, bgRgb, hex, bgHex) | Yes (rgb, hex, etc.) | No | Yes (rgb, hex, hsl, etc.) | Hex only (#RGB / #RRGGBB in Node 22+) |
| 256 colors | No | Yes (fg(n), bg(n)) | No | Yes (ansi256(n)) | No |
| Hyperlinks (OSC 8) | Yes (link(text, url) w/ markdown fallback) | Yes (link(text, url)) | No | No (requires terminal-link) | No |
| Color detection | Automatic (TTY, NO_COLOR, FORCE_COLOR, CI, Windows) | Automatic (w/ color depth downsampling) | Automatic (TTY, NO_COLOR, FORCE_COLOR, CI, Windows) | Automatic (Level 0–3 via supports-color, w/ downsampling) | Automatic (TTY, NO_COLOR, FORCE_COLOR, NODE_DISABLE_COLORS) |
| Instance / override | Yes (@mpen/ansi-colors/class) | Yes (new Ansis()) | Yes (createColors(bool)) | Yes (new Chalk({ level })) | Limited (stream option or env vars) |
| Dependencies | 0 | 0 | 0 | 0 (v5+) | Built-in |
Tree-shakeability & bundle size
@mpen/ansi-colors: Designed from the ground up for tree-shaking with modern bundlers (Rollup, esbuild, Rolldown, Vite, Webpack). Every formatter is an independent named export annotated with/* @__PURE__ */, andpackage.jsonspecifies"sideEffects": false. If you only importred, a bundler includes only the red escape codes and core formatter logic (~500 bytes minified), pruning all other colors, backgrounds, RGB/Hex logic, and hyperlink code. Overrides are isolated in the@mpen/ansi-colors/classsubpath so importing the class never pollutes the tree-shakeable root.ansis: Offers named ESM exports (import { red } from 'ansis'), but its ESM entry point re-exports destructured properties from a monolithic CommonJS file (./index.cjs). Furthermore, because every formatter inansisis an instance that supports chaining (e.g.red.bold.bgHex(...)), every single exported formatter holds references to the entire chaining engine and all color methods, preventing bundlers from eliminating unused styles.picocolors: Extremely lightweight in raw size (~2.5 KB minified), but ships as CommonJS and exports a single dynamically created object containing all 41 formatters (module.exports = createColors()). Bundlers cannot prune unused functions from this object, meaning every color is bundled regardless of how many you use.chalk: Built around a dynamic prototype chain (createChalk.prototype) and Proxy-based builders. It does not export individual color functions; all styling passes through the centralchalkinstance. Importing any style pulls in the entire library (~30–45 KB minified), including its color conversion tables andsupports-colorlogic.util.styleText: Because it is built directly into Node.js (v20.12.0+ / v22+), it adds zero bundle size in server-side Node.js applications. However, it cannot be tree-shaken into client-side browser bundles or portable cross-runtime packages without shipping Node polyfills.
Color detection
@mpen/ansi-colors: Lightweight automatic detection at module load time. HonorsNO_COLOR(disabling output if set and non-empty),FORCE_COLOR, CI environments, Windows platforms, and interactive TTY streams whereTERM !== 'dumb'. The detected state is exported ascolorSupportLevel. For cases requiring dynamic toggling or disabling in tests,@mpen/ansi-colors/classprovidesnew AnsiColors(boolean | ColorLevel).ansis: Performs deep terminal capability detection, distinguishing between monochromatic, 16-color, 256-color, and Truecolor (16-million color) environments. It automatically downsamples 24-bit Truecolor to 256 or 16 colors if the terminal does not support Truecolor, and respectsNO_COLORandFORCE_COLOR.picocolors: Uses lightweight inline detection similar to@mpen/ansi-colors, checkingNO_COLOR,FORCE_COLOR,--color/--no-colorCLI flags, TTY status,TERM, CI, and Windows. Color support can be toggled viacreateColors(boolean).chalk: Features the most comprehensive terminal detection viasupports-color. It detects four levels (0: off, 1: 16 colors, 2: 256 colors, 3: Truecolor), checks--color/--no-colorflags, OS versions, CI, and terminal programs. It downsamples colors to match the detected terminal level, and exportschalkStderrfor stderr detection.util.styleText: Uses Node's internal stream inspect logic, respectingNO_COLOR,FORCE_COLOR, andNODE_DISABLE_COLORS. You can pass a{ stream }option to evaluate color support for a specific stream (e.g.process.stderr).
Functions & available styles
@mpen/ansi-colors: Provides standard 16 foreground colors, 16 background colors (including bright variants), and 8 text modifiers (bold,dim,italic,underline,inverse,hidden,strikethrough,reset). Includes dedicated 24-bit Truecolor helpers (rgb,bgRgb,hex,bgHex) and ANSI OSC 8 clickable hyperlinks (link(text, url)) that automatically degrade to markdown links[text](url)when colors/ANSI sequences are disabled.ansis: Broad feature set with chained styling (ansis.red.bold('text')), tagged template literals (ansis.red`Error: ${ansis.cyan`file.js`} not found`), 256 colors (fg(n)/bg(n)), Truecolor (RGB/Hex), custom named CSS colors viaextend(), OSC 8 hyperlinks, and ANSI code stripping (strip()).picocolors: Minimalist 16-color and 8-modifier functional API. Omits Truecolor, 256 colors, hyperlinks, and chaining in favor of absolute minimal source code.chalk: Rich formatting with chained styling, tagged template literals, 256 colors, Truecolor across multiple color models (RGB, Hex, HSL, HSV, HWB), and automatic downsampling. Hyperlinks and ANSI stripping require separate companion packages (terminal-linkandstrip-ansi).util.styleText: Accepts format tokens or an array of tokens:styleText('red', text)orstyleText(['bold', 'red'], text). Supports 16 colors, bright variants, backgrounds, and standard modifiers. Node 22+ adds hex string colors (#RGB,#RRGGBB). Lacks RGB integer factories, tagged template literals, chaining, hyperlinks, and ANSI stripping.
Changelog
0.3.0
- Added
ColorLevelandcolorSupportLevel:None(0),Basic(1, 16 colors),Ansi256(2, 256 colors), andTrueColor(3, 24-bit color). - Deprecated
isColorSupportedandisTrueColorSupported, both as root exports and asAnsiColorsproperties. UsecolorSupportLevel > ColorLevel.NoneandcolorSupportLevel === ColorLevel.TrueColor, respectively. The deprecated booleans remain available for compatibility. - Added 256-color detection for
TERMvalues ending in-256coloror-256, Apple Terminal, andFORCE_COLOR=2. - Breaking:
AnsiColorsnow accepts a singleboolean | ColorLevelargument.falseselects level 0,trueselects level 3, and omitting the argument uses automatic detection. The second constructor argument has been removed; pass the desiredColorLevelinstead.
0.2.0
Version 0.2.0 removes the default export and createColors from the package root. Replace grouped API usage with either the tree-shakeable root exports or the class subpath:
// Before
import createColors from '@mpen/ansi-colors'
const ac = createColors(false)
// After: grouped, explicitly configurable API
import { AnsiColors } from '@mpen/ansi-colors/class'
const ac = new AnsiColors(false)For automatically detected support, prefer import * as ac from '@mpen/ansi-colors' and call formatters directly.
License
MIT © Mark Penner. Portions derived from picocolors (Copyright © Oleksii Raspopov, Kostiantyn Denysov, Anton Verinov).
