Skip to content

webdiscus/ansis

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

195 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

ansis
Make terminals a little more colorful 🌈

[ANSI S]tyles

npm node Test codecov downloads install size

Ansis demo

ANSI color library for use in terminals, CI environments, and Chromium-based browsers.
Ansis is focused on small size and speed while providing rich functionality and handling edge cases.

// Named imports - for cleaner, more readable code
import { red, cyan, bold, hex, rgb } from 'ansis';

// Clean chained syntax with template literals - no extra parentheses
console.log(bold.bgRed` FAIL `);

// Nested templates - no string concatenation needed
console.log(red`✖ Error: ${cyan`file.js`} not found`);

// Truecolor: hex and rgb
console.log(hex('#FF75D1').bold`Pink`);
console.log(rgb(224, 17, 95).italic`Ruby`);

🔗 Shortcuts

✨ Highlights

🎨 Colors - 16 · 256 · Truecolor (hex/rgb) · Named colors (orange, pink ...)
✍️ Syntax - Chained · Template literals · Nested templates
⚙️ Works  - ESM · CJS · TS · Node 10+ · Bun · Deno · CI · Chromium browsers
🧠 Smart  - Auto color detection · Fallback (truecolor → 256 → 16 → b&w) · NO_COLOR · FORCE_COLOR
📦 Tiny   - 5.8 kB · Drop-in replacement for Chalk (44 kB)

⚡ Performance

Ansis is the fastest when using 2 or more styles, which is the common real-world use case.

Library 1 style 2+ styles
ansis 60M ops/sec 🏆 60M ops/sec
picocolors 🏆 109M ops/sec 58M ops/sec
chalk 55M ops/sec 47M ops/sec
util.styleText 0.5M ops/sec 0.5M ops/sec

📊 Full benchmarks →

💡 Features

🎨 Colors & Styles

✍️ Syntax

🛠️ Utilities

  • Strip ANSI codes: ansis.strip(red('text')) → plain 'text'
  • Raw escape codes: open / close - `${red.open}Error${red.close} file not found`

💻 Environment

⚙️ Compatibility

🎯 You might also like

  • flaget - CLI argument parsing. A smaller (5 kB) and faster alternative to yargs-parser (85 kB)
  • HTML bundler - Plugin for Webpack to generate static sites from templates (html, ejs, hbs, pug, ...)

⚖️ Alternatives

chalk, picocolors, colorette, kleur, ansi-colors, kolorist, cli-color, colors-cli, colors.js, tinyrainbow

Since Node.js 22 supports ANSI styling natively via util.styleText(), it is recommended for simple use cases where 16 colors are enough and top performance is not critical. See styleText() limitations.

Compare features 📊 Benchmarks 🧩 Handling edge cases

Install

npm install ansis

For Node.js 10–12+ use special build npm install ansis@node10

Usage

ESM

import ansis, { red, bold, fg, hex, rgb } from 'ansis';

CJS

const ansis = require('ansis');
const { red, bold, fg, hex, rgb } = require('ansis');

Chained syntax

All colors, styles and functions are chainable. Each color or style can be combined in any order.

import { red, bold, hex } from 'ansis';

red.bold`text`;
hex('#FF75D1').bgCyan.bold`text`;
bold.hex('#FF75D1').bgCyan`text`;

Template literals

Omit parentheses to keep your code clean:

import { red, yellow, green } from 'ansis';

red`Error`; // no parentheses
red`Red ${yellow`Yellow ${green`Green`} Yellow`} Red`; // deep nested templates

Escape sequences work exactly as in regular strings:

red`Hello\nWorld`; // two lines in red
red`prev\\next`;   // one line: prev\next

ANSI Styles

dim bold italic underline strikethrough inverse visible hidden reset

ANSI 16 colors

There are 16 basic colors: 8 standard and 8 bright variants.

Example Color Background Bright Example Bright Color Bright Background
black bgBlack gray bgGray
red bgRed redBright bgRedBright
green bgGreen greenBright bgGreenBright
yellow bgYellow yellowBright bgYellowBright
blue bgBlue blueBright bgBlueBright
magenta bgMagenta magentaBright bgMagentaBright
cyan bgCyan cyanBright bgCyanBright
white bgWhite whiteBright bgWhiteBright

ANSI 256 colors

  • Foreground: fg(code) - chalk.ansi256(code) equivalent
  • Background: bg(code) - chalk.bgAnsi256(code) equivalent
import { bold, fg, bg } from 'ansis';

fg(96)`Bright Cyan`;
bg(105).fg(96)`Cyan text on magenta background`;
bold.fg(96).underline`Bold underline Bright Cyan`;

256 color codes

See ANSI color codes.

Fallback

If a terminal supports only 16 colors then ANSI 256 colors will be interpolated into base 16 colors.

Truecolor

  • Foreground: hex() rgb()
  • Background: bgHex() bgRgb()
import { bold, hex, rgb, bgHex } from 'ansis';

hex('#E0115F').bold`Bold Ruby`;
rgb(224, 17, 95).italic`Italic Ruby`;
bold.hex('#E0115F').bgHex('#96C')`Ruby text on amethyst background`;

See also named truecolors.

Fallback

Ansis automatically interpolates to the best available color level.

Truecolor → 256 colors → 16 colors → no colors (b&w)

output

Named truecolors

Register any hex color as a named style via extend(). Background methods bg* are generated automatically.

import ansis from 'ansis';

const myTheme = {
  orange: '#ffa500',
  pink:   '#ffc0cb',
};

const color = ansis.extend(myTheme);

color.orange.bold`orange bold`;       // extended first in chain
color.bgOrange`orange background`;    // auto-generated bg
color.pink`pink foreground`;
color.bgPink`pink background`;        // auto-generated bg
color.red`built-in red still works`;  // built-in remains intact

Warning

Put extended colors first in the chain: color.orange.boldcolor.bold.orange

Tip

For all CSS named colors use css-color-names package.

output

Open in StackBlitz

Example: extend with CSS color names

import ansis from 'ansis';
import colorNames from 'css-color-names'; // { pink: '#ffc0cb', orange: '#ffa500', ... }

const color = ansis.extend(colorNames);

color.pink('Pink foreground');
color.bgPink('Pink background'); // auto-generated bg

Tip

Need help picking a color name? Try the Name that Color tool - paste a hex and get its closest color name.


Color support

Ansis automatically detects the supported color level:

  • 0 – No color
  • 1 – Basic ANSI (16 colors)
  • 2 – Extended ANSI (256 colors)
  • 3 – Truecolor (16 million colors)

Check the detected level at runtime:

import ansis from 'ansis';

console.log(ansis.level);         // 0 | 1 | 2 | 3
console.log(ansis.isSupported()); // true -> level >= 1 (at least 16 colors supported)

To override the detected level, create an instance of Ansis directly with the desired level:

import { Ansis } from 'ansis';

const noColor  = new Ansis(0);  // always plain text, no ANSI codes
const basic    = new Ansis(1);  // 16 colors; hex/rgb fall back to nearest
const auto     = new Ansis();   // auto-detect (same as default import)

console.log(noColor.red`foo`);              // plain text, no ANSI codes
console.log(basic.hex('#FFAB40')`Orange`);  // falls back to yellowBright
Example: disable colors via custom CLI flag, e.g. --save-to-log
import { Ansis } from 'ansis';

/**
 * Ansis instance for CLI that can be initialized with no colors mode
 * needed for outputs where we don't want to have colors.
 *
 * @param  {boolean} noColors Disable colors
 * @return {Ansis} Default or custom instance
 */
function safeAnsis(noColors) {
  return noColors
    ? new Ansis(0) // disable colors
    : new Ansis(); // auto detect color support
}

// handle a special CLI flag to disable colors
const ansis = safeAnsis(process.argv.includes('--save-to-log'))

Auto-detection

Ansis detects color support from the terminal environment automatically:

  • Reads TERM and COLORTERM environment variables
  • In CI environments, checks CI and assumes at least 16 colors
  • GitHub Actions is explicitly detected as truecolor
Supported terminals and CI environments
Terminal ANSI 16
colors
ANSI 256
colors
True
Color
env.
TERM
env.
COLORTERM
Specifically ENV variables
Azure CI dumb TF_BUILD
AGENT_NAME
GitHub CI dumb CI, GITHUB_ACTIONS
GitTea CI dumb CI, GITEA_ACTIONS
GitLab CI dumb CI, GITLAB_CI
Travis CI dumb TRAVIS
PM2
not isTTY
✅[^1] ✅[^1] ✅[^1] dumb PM2_HOME
pm_id
JetBrains TeamCity
>=2020.1.1
TEAMCITY_VERSION
JetBrains IDEA xterm-256color TERMINAL_EMULATOR='JetBrains-JediTerm'
VS Code xterm-256color truecolor
Windows
Terminal
✅[^2]
Windows
PowerShell
✅[^2]
macOS Terminal xterm-256color
iTerm xterm-256color truecolor
Kitty xterm-kitty truecolor
KDE Konsole xterm-256color truecolor
  • ^1 Colors supported depends on actual terminal.
  • ^2: The Windows terminal supports true color since Windows 10 revision 14931 (2016-09-21).

See also:

Environment & CLI options

Ansis supports the following environment variables and CLI flags.

Environment variables

NO_COLOR

Set to any non-empty value (1, true) to disable color output (no-color.org):

NO_COLOR=1 node app.js

FORCE_COLOR

Force a specific color level regardless of terminal support (force-color.org):

Value Behavior
0 or false Disable colors (level 0)
1 Enable 16 colors (level 1)
2 Enable 256 colors (level 2)
3 Enable truecolor (level 3)
true or (unset) Auto-detect with fallback to 16 colors if nothing detected

Important

In Node.js FORCE_COLOR=true and FORCE_COLOR=1 both enable 16 colors.
In Ansis, the value 1 means level 1 and strictly set 16 colors, while true triggers auto-detection.

COLORTERM

Hint the color level via terminal emulator convention:

Value Level
ansi 16 colors (level 1)
ansi256 256 colors (level 2)
truecolor or 24bit Truecolor (level 3)

CLI flags

Pass --no-color or --color directly to your script:

./app.js              # auto-detect
./app.js --no-color   # disable colors
./app.js --color      # force colors (useful when piping output)

Note

CLI flags take precedence over environment variables.

Quick reference

node app.js                          # auto-detect
node app.js > log.txt                # no colors (non-TTY)

NO_COLOR=1 node app.js               # force off
FORCE_COLOR=0 node app.js            # force off

FORCE_COLOR=1 node app.js > log.txt  # force 16 colors
FORCE_COLOR=2 node app.js > log.txt  # force 256 colors
FORCE_COLOR=3 node app.js > log.txt  # force truecolor

node app.js --no-color               # disable via flag
node app.js --color > log.txt        # enable via flag

Edge cases

Break style at New Line

Ansis and Chalk add a style break at each new line to correctly display multi-line text.
However, Picocolors doesn't handle this case.

ansis.bgRed('\n ERROR \n') + ansis.cyan('The file not found!') // ✅
chalk.bgRed('\n ERROR \n') + chalk.cyan('The file not found!') // ✅
pico.bgRed('\n ERROR \n') + pico.cyan('The file not found!')   // ❌

Break style at New Line

Nested template strings

Only Ansis handles this very useful use case.

ansis.red`R ${ansis.green`G ${ansis.blue`B`} G`} R` // ✅
chalk.red`R ${chalk.green`G ${chalk.blue`B`} G`} R` // ❌
pico.red`R ${pico.green`G ${pico.blue`B`} G`} R`    // ❌

Nested template strings

Handling arguments

Compare how different libraries handle various input arguments in their functions.

ansis.red()          // ✅ ''
chalk.red()          // ✅ ''
pico.red()           // ❌ \e[31mundefined\e[39m

ansis.red(undefined) // ✅ ''
chalk.red(undefined) // ❌ \e[31mundefined\e[39m
pico.red(undefined)  // ❌ \e[31mundefined\e[39m

ansis.red(null)      // ✅ ''
chalk.red(null)      // ❌ \e[31mnull\e[39m
pico.red(null)       // ❌ \e[31mnull\e[39m

ansis.red('')        // ✅ ''
chalk.red('')        // ✅ ''
pico.red('')         // ❌ \e[31m\e[39m

ansis.reset()        // ✅ \e[0m
chalk.reset()        // ❌ ''
pico.reset()         // ❌ \e[0mundefined\e[0m
Library c.reset() c.red() c.red(undefined) c.red(null) c.red('')
ansis \e[0m '' '' '' ''
chalk '' '' 'undefined' 'null' ''
picocolors undefined 'undefined' 'undefined' 'null' 'ESC'
tinyrainbow undefined 'undefined' 'undefined' 'null' 'ESC'
colorette '' '' '' 'null' ''
kleur [object] [object] [object] 'null' 'ESC'
ansi-colors '' '' '' '' ''
kolorist undefined 'undefined' 'undefined' 'null' 'ESC'
colors.js '' '' 'undefined' 'null' ''
cli-color - 'ESC' 'ESC' 'ESC' 'ESC'
colors-cli - Error 'undefined' 'null' 'ESC'

Legend:

  • '' - Returns an empty string without ANSI escape codes. This is the correct and expected behavior.
  • \e[0m - Returns the reset escape code.
  • 'ESC' - Returns an empty string containing ANSI escape codes, e.g., \e[31m\e[39m.
  • 'undefined' - Returns the styled string undefined.
  • 'null' - Returns the styled string null.
  • [object] - Returns an object of the library instance.
  • - - The feature is not supported.
  • Error - Causes a fatal error.

Other arguments are correctly handled by all libraries:

c.red(0)       // '0' in red
c.red(false)   // 'false' in red
c.red(true)    // 'true' in red
c.red(5/'1px') // 'NaN' in red
c.red(1/0)     // 'Infinity' in red

Ansis vs styleText()

Since Node v22, the built-in util.styleText() has been officially introduced, supporting standard modifiers - the basic 16 colors and styles.

Where it works

Ansis

✅ Node v10+
✅ Chromium-based browsers and Safari
⚠️ Firefox DevTools don't render ANSI escape sequences

styleText

✅ Node v22+ (native)
❌ Node only - no browser support

Performance

In practical benchmarks, styleText() is dramatically slower, 100x slower than Ansis:

ansis.red('text');        // 59.646.465 ops/sec
styleText('red', 'text'); //    579.832 ops/sec

See full benchmarks.

Color support detection

Ansis

  • Auto-detects terminal, TTY, CI and browser color support with automatic fallback
  • Supports NO_COLOR FORCE_COLOR COLORTERM --no-color --color
  • ansis.level returns the detected color level

styleText

  • Auto-detects terminal color support
  • Supports only NO_COLOR FORCE_COLOR NODE_DISABLE_COLORS

Simple styling

import { green } from 'ansis';
import { styleText } from 'node:util';

green`Success!`; // ansis
styleText('green', 'Success!');

green.bold`Success!`; // ansis
styleText(['green', 'bold'], 'Success!');

Nested styling

import { red, cyan } from 'ansis';
import { styleText } from 'node:util';

red`Error: ${cyan.bold`file.js`} not found!`; // ansis
styleText('red', `Error: ${styleText(['cyan', 'bold'], 'file.js')} not found!`);

Truecolor

Ansis: hex() rgb()

styleText: Limited to 16 ANSI colors.


Compatibility

Check the minimum version of your tool required for compatibility with the latest Ansis.

Tool Version Compatibility Supports
Node.js v14+ ✅ Full support CJS, ESM
Deno v2.0+ ✅ Full support CJS, ESM
TypeScript/tsc v5.0+ ✅ Full support CJS, ESM
esbuild v0.8+ ✅ Full support CJS, ESM
swc v1.2+ ✅ Full support CJS, ESM, FAUX
tsup v4.0+ ✅ Full support CJS, ESM, FAUX
tsx v3.0+ ✅ Full support CJS, ESM
Rollup v2.0+ ✅ Full support CJS, ESM
Rolldown v1.0.0-beta.8+ ✅ Full support CJS, ESM
Vite v2.5+ ✅ Full support ESM
Turbo v1.0+ ✅ Full support CJS, ESM
Webpack v5.0+ ✅ Full support CJS, ESM

Supports:

  • CJS: CommonJS module support.
  • ESM: ECMAScript module support.
  • FAUX: Fake or non-standard approach to module resolution (seen in swc).

Browser Compatibility for ANSI Codes

Browser Version Colors Supported
Chrome v20+ TrueColor (16M)
Safari v10+ TrueColor (16M)
Edge v12+ TrueColor (16M)
Opera v12+ TrueColor (16M)
Brave v1.0+ TrueColor (16M)
Vivaldi v1.0+ TrueColor (16M)

Warning

Firefox doesn't natively support ANSI codes in the developer console.


⭐️ Star History

If you find this useful, please ⭐️ the repo.

Star History Chart


License

ISC

About

CJS/ESM ANSI color library for terminals, CI and Chromium-based browser consoles. Compatible with Bun, Deno, Next.JS.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project

Contributors