The Node.js library to colorize terminal and console output with ANSI colors & styles
Ansis is a smaller and faster alternative to Chalk with additional useful features and clean syntax.
For example:
green`Succeful!`
red`Error!`
black.bgYellow`Warning!`
hex('#E0115F').bold.underline('Hello World!')
π Install and Quick Start
π Why yet one lib?
- Quality is first, test coverage 100%.
- Ansis has a lot of useful features, compare with other libraries.
- Ansis is one of the smallest, 3.4 KB only.
- Ansis is one of the fastest.
- Ansis is stable, continuously developing and improving.
- Ansis is open for your feature requests.
See the features comparison and benchmarks of most popular Node.js libraries:
chalk, colors.js, colorette, picocolors, kleur, kolorist, ansi-colors, cli-color, colors-cli.
π‘ Highlights
π What's New in v3
- NEW added detection of supported color space: TrueColor, 256 colors, 16 colors, no color (black & white)
- NEW added fallback to supported color space: TrueColor β> 256 colors β> 16 colors β> no colors
β οΈ Warning
The v3
has the BREAKING CHANGES (removed not widely supported styles and deprecated methods).
For details see the changelog.
βQuestion / Feature Request / Bug
If you have discovered a bug or have a feature suggestion, feel free to create
an issue on GitHub.
Install and Quick Start
npm install ansis
You can import default module or named colors with ESM or CommonJS syntax.
import ansis from 'ansis';
import { red, green, blue } from 'ansis';
or
const ansis = require('ansis');
const { red, green, blue } = require('ansis');
See the list of the ANSI colors and styles.
console.log(ansis.green('Success!'));
console.log(green('Success!'));
console.log(green`Success!`);
console.log(green.bold`Success!`);
console.log(red`The ${blue.underline`file.js`} not found!`);
Basic example Hello World!
:
import { red, black, inverse, reset } from 'ansis';
console.log(green`Hello ${inverse`ANSI`} World!
${black.bgYellow`Warning:`} ${cyan`/path/to/file.js`} ${red`not found!`}`);
Output:
Named import
The ansis
supports both the default import
and named import
.
import ansis from 'ansis';
ansis.red.bold('text');
You can import named colors, styles and functions. All imported colors and styles are chainable
.
import { red, hex, italic } from 'ansis';
red.bold('text');
Default import and named import can be combined.
import ansis, { red } from 'ansis';
const redText = red('text');
const text = ansis.strip(redText);
Template literals
The ansis
supports both the function syntax red('error')
and template literals red`error`
.
The template literals
allow you to make a complex template more readable and shorter.
The function syntax
can be used to colorize a variable.
import { red } from 'ansis';
let message = 'error';
red(message);
red`text`;
red`text ${message} text`;
Chained syntax
All colors, styles and functions are chainable. Each color or style can be combined in any order.
import { red, bold, italic, hex } from 'ansis';
red.bold`text`;
hex('#FF75D1').bgCyan.bold`text`;
bold.bgHex('#FF75D1').cyan`text`;
italic.bold.yellow.bgMagentaBright`text`;
Nested syntax
You can nest functions and template strings within each other.
None of the other libraries (chalk, kleur, colorette, colors.js etc.) support nested template strings.
Nested template strings:
import { red, green } from 'ansis';
red`red ${green`green`} red`;
Deep nested chained styles:
import { red, green, cyan, magenta, yellow, italic, underline } from 'ansis';
red(`red ${italic(`red italic ${underline(`red italic underline`)}`)} red`);
green(
`green ${yellow(
`yellow ${magenta(
`magenta ${cyan(
`cyan ${red.italic.underline`red italic underline`} cyan`,
)} magenta`,
)} yellow`,
)} green`,
);
Output:
Multiline nested template strings:
import { red, green, hex, visible, inverse } from 'ansis';
const orange = hex('#FFAB40');
let cpu = 33;
let ram = 44;
let disk = 55;
visible`
CPU: ${red`${cpu}%`}
RAM: ${green`${ram}%`}
DISK: ${orange`${disk}%`}
`;
inverse`
CPU: ${red`${cpu}%`}
RAM: ${green`${ram}%`}
DISK: ${orange`${disk}%`}
`;
Output:
Base ANSI 16 colors and styles
Colors and styles have standard names used by many popular libraries, such
as chalk, colorette, kleur.
Foreground colors | Background colors | Styles |
---|
black | bgBlack | dim |
red | bgRed | bold |
green | bgGreen | italic |
yellow | bgYellow | underline |
blue | bgBlue | strikethrough (alias strike ) |
magenta | bgMagenta | inverse |
cyan | bgCyan | visible |
white | bgWhite | hidden |
blackBright aliases:
grey
gray US spelling | bgBlackBright aliases:
bgGrey
bgGray US spelling | reset |
redBright | bgRedBright | |
greenBright | bgGreenBright | |
yellowBright | bgYellowBright | |
blueBright | bgBlueBright | |
magentaBright | bgMagentaBright | |
cyanBright | bgCyanBright | |
whiteBright | bgWhiteBright | |
Extend base colors
Defaults, the imported ansis
instance contains base styles and colors.
To extend base colors with custom color names for TrueColor use the ansis.extend()
method.
import ansis from 'ansis';
ansis.extend({
pink: '#FF75D1',
orange: '#FFAB40',
});
ansis.pink('text');
ansis.orange('text');
Usage example with TypeScript:
import ansis, { AnsiColorsExtend } from 'ansis';
ansis.extend({
pink: '#FF75D1',
orange: '#FFAB40',
});
const write = (style: AnsiColorsExtend<'pink' | 'orange'>, message: string) => {
console.log(ansis[style](message));
}
write('red', 'message');
write('pink', 'message');
write('orange', 'message');
write('unknown', 'message');
ANSI 256 colors
The pre-defined set of 256 colors.
Code range | Description |
---|
0 - 7 | standard colors |
8 - 15 | bright colors |
16 - 231 | 6 Γ 6 Γ 6 cube (216 colors) |
232 - 255 | grayscale from black to white in 24 steps |
Foreground function: ansi256(code)
has short alias fg(code)
Background function: bgAnsi256(code)
has short alias bg(code)
The ansi256()
and bgAnsi256()
methods are implemented for compatibility with the chalk
API.
See ANSI color codes.
import { bold, ansi256, fg, bgAnsi256, bg } from 'ansis';
ansi256(96)`Bright Cyan`;
fg(96)`Bright Cyan`;
bgAnsi256(105)`Bright Magenta`;
bg(105)`Bright Magenta`;
ansi256(96).bold`bold Bright Cyan`;
bold.ansi256(96).underline`bold underline Bright Cyan`;
bgAnsi256(105).ansi256(96)`cyan text on magenta background`
bg(105).fg(96)`cyan text on magenta background`
TrueColor
You can use the hex
or rgb
format.
Foreground function: hex()
rgb()
Background function: bgHex()
bgRgb()
import { bold, hex, rgb, bgHex, bgRgb } from 'ansis';
hex('#E0115F').bold`bold Ruby`;
hex('#96C')`Amethyst`;
rgb(224, 17, 95).italic`italic Ruby`;
bgHex('#E0115F')`Ruby`;
bgHex('#96C')`Amethyst`;
bgRgb(224, 17, 95)`Ruby`;
bold.hex('#E0115F').bgHex('#96C')`ruby bold text on amethyst background`
Fallback
The ansis
supports fallback to supported color space.
TrueColor β> 256 colors β> 16 colors β> no colors (black & white)
If you use the hex()
, rgb()
or ansis256()
functions in a terminal not supported TrueColor or 256 colors, then colors will be interpolated.
Use ANSI codes
You can use the ANSI escape codes with open
and close
properties for each style.
import { red, bold } from 'ansis';
console.log(`Hello ${red.open}ANSI${red.close} World!`);
const myStyle = bold.italic.black.bgHex('#E0115F');
console.log(`Hello ${myStyle.open}ANSI${myStyle.close} World!`);
Strip ANSI codes
The Ansis class contains the method strip()
to remove all ANSI codes from string.
import ansis from 'ansis';
const ansiString = ansis.green`Hello World!`;
const string = ansis.strip(ansiString);
The variable string
will contain the pure string without ANSI codes.
New lines
Supports correct style break at the end of line
.
import { bgGreen } from 'ansis';
console.log(bgGreen`\nAnsis\nNew Line\nNext New Line\n`);
Shortcuts / Themes
Define your own themes:
import ansis from 'ansis';
const theme = {
error: ansis.red.bold,
info: ansis.cyan.italic,
warning: ansis.black.bgYellowBright,
ruby: ansis.hex('#E0115F'),
};
theme.error('error');
theme.info('info');
theme.warning('warning');
theme.ruby('Ruby color');
CLI
Defaults, the output in terminal console is colored and output in a file is uncolored.
Environment variables
To force disable or enable colored output use environment variables NO_COLOR
and FORCE_COLOR
.
The NO_COLOR
variable should be presents with any not empty value.
The value is not important, e.g., NO_COLOR=1
NO_COLOR=true
disable colors.
See standard description by NO_COLOR.
The FORCE_COLOR
variable should be presents with one of values:
FORCE_COLOR=0
force disable colors
FORCE_COLOR=1
force enable colors
For example, app.js:
import { red } from 'ansis';
console.log(red`red color`);
Execute the script in a terminal:
$ node app.js # colored output in terminal
$ node app.js > log.txt # output in file without ANSI codes
$ NO_COLOR=1 node app.js # force disable colors, non colored output in terminal
$ FORCE_COLOR=0 node app.js # force disable colors, non colored output in terminal
$ FORCE_COLOR=1 node app.js > log.txt # force enable colors, output in file with ANSI codes
CLI arguments
Use arguments --no-color
or --color=false
to disable colors and --color
to enable ones.
For example, an executable script app.js:
#!/usr/bin/env node
import { red } from 'ansis';
console.log(red`red color`);
Execute the script in a terminal:
$ ./app.js # colored output in terminal
$ ./app.js --no-color # non colored output in terminal
$ ./app.js --color=false # non colored output in terminal
$ ./app.js > log.txt # output in file without ANSI codes
$ ./app.js --color > log.txt # output in file with ANSI codes
$ ./app.js --color=true > log.txt # output in file with ANSI codes
Warning
The command line arguments have a higher priority than environment variable.
Color support
Ansis automatically detects the supported color space:
- TrueColor
- ANSI 256 colors
- ANSI 16 colors
- black & white (no color)
There is no standard way to detect which color space is supported.
The most common way to detect color support is to check the TERM
and COLORTERM
environment variables.
CI systems can be detected by checking for the existence of the CI
and other specifically environment variables.
Combine that with the knowledge about which operating system the program is running on, and we have a decent enough way to detect colors.
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 |
JetBrains TeamCity >=2020.1.1 | β
| β
| β | | | TEAMCITY_VERSION |
JetBrains IDEA | β
| β
| β
| xterm-256color | | TERMINAL_EMULATOR='JetBrains-JediTerm' |
VS Code | β
| β
| β
| xterm-256color | truecolor | |
Windows Terminal | β
| β
| β
* | | | |
Windows PowerShell | β
| β
| β
* | | | |
macOS Terminal | β
| β
| β | xterm-256color | | |
iTerm | β
| β
| β
| xterm-256color | truecolor | |
Terminal emulator Kitty | β
| β
| β
| xterm-kitty | | |
*The Windows terminal supports true color since Windows 10 revision 14931 (2016-09-21).
Used reference: So you want to render colors in your terminal.
Comparison of most popular libraries
Run the command to see the support of some features by various libraries:
npm run compare
Library ________________ - name - bundle size - named import - naming colors | ANSI base colors | ANSI 256 colors | True Color | Chained syntax | Nested template strings | New Line | Fallbacks | Supports ENV vars CLI flags |
---|
colors.js 18.1KB
β named import
β standard | 16 colors | β | β | β
| β | β
| no color | FORCE_COLOR
--no-color
--color |
colors-cli 8.6KB
β named import
β standard | 16 colors | β
| β | β
| β | β
| no color | --no-color
--color |
cli-color
β named import
β
standard | 16 colors | β
| β | β
| β | β | 16 colors no color | NO_COLOR |
ansi-colors 5.8KB
β named import
β
standard | 16 colors | β | β | β
| β | β
| β | FORCE_COLOR |
colorette 3.3KB
β
named import
β
standard | 16 colors | β | β | β | β | β | no color | NO_COLOR
FORCE_COLOR
--no-color
--color |
picocolors 2.6KB
β named import
β
standard | 8 colors | β | β | β | β | β | no color | NO_COLOR
FORCE_COLOR
--no-color
--color |
kleur 2.7KB
β
named import
β
standard | 8 colors | β | β | β
| β | β | no color | NO_COLOR
FORCE_COLOR |
kolorist 6.8KB
β
named import
β standard | 16 colors | β
| β
| β | β | β | 256 color β no color | NO_COLOR
FORCE_COLOR |
chalk 15KB
β named import
β
standard | 16 colors | β
| β
| β
| β | β
| 256 color 16 colors no color | NO_COLOR
FORCE_COLOR
--no-color
--color |
ansis 3.4KB
β
named import
β
standard | 16 colors | β
| β
| β
| β
| β
| 256 color 16 colors no color | NO_COLOR
FORCE_COLOR
--no-color
--color |
Note
Code size
The size of distributed code that will be loaded via require
or import
into your app. It's not a package size.
Named import
import { red, green, blue } from 'lib';
or
const { red, green, blue } = require('lib');
Naming colors
- standard: colors have standard names, e.g.:
red
, redBright
, bgRed
, bgRedBright
- non-standard: colors have lib-specific names, e.g.:
brightRed
, bgBrightRed
, red_b
, red_btt
ANSI 256 colors
The method names:
TrueColor
The method names:
Chained syntax
lib.red.bold('text')
Nested template strings
lib.red`text ${lib.cyan`nested`} text`
New line
Correct break styles at end-of-line
.
lib.bgGreen(`First Line
Next Line`);
Show ANSI demo
git clone https://github.com/webdiscus/ansis.git
cd ./ansis
npm i
npm run demo
Benchmark
To measure performance is used benchmark.js.
βΌοΈ Warning
Don't trust other test results using vitest benchmark.
The vitest benchmark
generate FALSE/unreal results.
For example, the results of the simple bench:
chalk.red('foo') - 7.000.000 ops/sec
ansis.red('foo') - 23.000.000 ops/sec (x3 faster is WRONG result)
The real performance results of chalk
and ansis
in this test are very close.
Run benchmark
git clone https://github.com/webdiscus/ansis.git
cd ./ansis
npm i
npm run bench
Tested on
MacBook Pro 16" M1 Max 64GB
macOS Monterey 12.1
Node.js v16.13.1
Terminal iTerm2
Colorette bench
The benchmark used in colorette
.
c.red(`${c.bold(`${c.cyan(`${c.yellow('yellow')}cyan`)}`)}red`);
+ colorette 4,572,582 ops/sec very fast
picocolors 3,841,124 ops/sec very fast
-> ansis 2,725,758 ops/sec fast
chalk 2,287,146 ops/sec fast
kleur/colors 2,281,415 ops/sec fast
kleur 2,228,639 ops/sec fast
ansi-colors 1,265,615 ops/sec slow
colors.js 1,158,572 ops/sec slow
cli-color 470,320 ops/sec too slow
colors-cli 109,811 ops/sec too slow
Base colors
const colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'];
colors.forEach((color) => c[color]('foo'));
+ picocolors 8,265,628 ops/sec very fast
-> ansis 6,197,754 ops/sec fast
kleur 5,455,121 ops/sec fast
chalk 4,428,884 ops/sec fast
kleur/colors 2,074,111 ops/sec slow
colorette 1,874,506 ops/sec slow
ansi-colors 1,010,628 ops/sec slow
colors.js 640,101 ops/sec too slow
cli-color 305,690 ops/sec too slow
colors-cli 104,962 ops/sec too slow
Chained styles
const colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'];
colors.forEach((color) => c[color].bold.underline.italic('foo'));
+ ansis 5,515,868 ops/sec very fast
chalk 1,234,573 ops/sec fast
kleur 514,035 ops/sec slow
ansi-colors 158,921 ops/sec too slow
cli-color 144,837 ops/sec too slow
colors.js 138,219 ops/sec too slow
colors-cli 52,732 ops/sec too slow
kleur/colors (not supported)
colorette (not supported)
picocolors (not supported)
Nested calls
const colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'];
colors.forEach((color) => c[color](c.bold(c.underline(c.italic('foo')))));
+ picocolors 942,592 ops/sec very fast
colorette 695,350 ops/sec fast
kleur 648,195 ops/sec fast
kleur/colors 561,111 ops/sec fast
-> ansis 558,575 ops/sec fast
chalk 497,292 ops/sec fast
ansi-colors 260,316 ops/sec slow
colors.js 166,425 ops/sec slow
cli-color 65,561 ops/sec too slow
colors-cli 13,800 ops/sec too slow
Nested styles
c.red(
`a red ${c.white('white')} red ${c.red('red')} red ${c.cyan('cyan')} red ${c.black('black')} red ${c.red('red')} red
${c.red('red')} red ${c.red('red')} red ${c.red('red')} red ${c.red('red')} red ${c.red('red')} red ${c.red('red')} red
${c.green('green')} red ${c.red('red')} red ${c.yellow('yellow')} red ${c.blue('blue')} red ${c.red('red')} red
${c.magenta('magenta')} red ${c.red('red')} red ${c.red('red')} red ${c.red('red')} red ${c.red('red')} red
${c.red('red')} red ${c.red('red')} red ${c.red('red')} red ${c.red('red')} red ${c.red('red')} red
${c.black('black')} red ${c.yellow('yellow')} red ${c.red('red')} red ${c.red('red')} red ${c.red('red')} red
${c.yellow('yellow')} red ${c.red('red')} red ${c.red('red')} red ${c.red('red')} red ${c.red('red')} red
${c.green('green')} red ${c.red('red')} red ${c.red('red')} red ${c.red('red')} red ${c.red('red')} red
${c.magenta('magenta')} red ${c.red('red')} red ${c.red('red')} red ${c.cyan('cyan')} red ${c.red('red')} red
${c.cyan('cyan')} red ${c.red('red')} red ${c.red('red')} red ${c.red('red')} red ${c.red('red')} red message`
);
+ picocolors 243,975 ops/sec very fast
colorette 243,139 ops/sec very fast
kleur/colors 234,132 ops/sec very fast
kleur 221,446 ops/sec very fast
-> ansis 211,868 ops/sec very fast
chalk 189,960 ops/sec fast
ansi-colors 121,451 ops/sec slow
colors.js 89,633 ops/sec too slow
cli-color 41,657 ops/sec too slow
colors-cli 14,264 ops/sec too slow
Deep nested styles
c.green(
`green ${c.cyan(
`cyan ${c.red(
`red ${c.yellow(
`yellow ${c.blue(
`blue ${c.magenta(`magenta ${c.underline(`underline ${c.italic(`italic`)} underline`)} magenta`)} blue`
)} yellow`
)} red`
)} cyan`
)} green`
);
+ colorette 1,131,757 ops/sec very fast
picocolors 1,002,649 ops/sec very fast
-> ansis 882,220 ops/sec very fast
chalk 565,965 ops/sec fast
kleur/colors 478,547 ops/sec fast
kleur 464,004 ops/sec fast
colors.js 451,592 ops/sec fast
ansi-colors 362,733 ops/sec slow
cli-color 213,441 ops/sec slow
colors-cli 40,340 ops/sec too slow
HEX colors
Only two libraries support TrueColor: ansis
and chalk
c.hex('#FBA')('foo');
+ ansis 4,944,572 ops/sec very fast
chalk 2,891,684 ops/sec fast
colors.js (not supported)
colorette (not supported)
picocolors (not supported)
cli-color (not supported)
colors-cli (not supported)
ansi-colors (not supported)
kleur/colors (not supported)
kleur (not supported)
Testing
npm run test
will run the unit and integration tests.
npm run test:coverage
will run the tests with coverage.
Also See
Most popular ANSI libraries for Node.js
:
License
ISC