Ansis is the tiny and faster compatible alternative to Chalk with even more useful features.
Colorize your output in a terminal with clean syntax,
e.g., green`Hello World!`
red`Error!`
black.bgYellow`Warning!`
.
Why yet one lib?
See comparison
and benchmarks of most popular Node.js libraries:
chalk
, colors.js
, colorette
, picocolors
, kleur
, ansi-colors
, cli-color
, colors-cli
.
- supports both ESM and CommonJS
- supports Deno, Next.JS runtime
- up to x3 faster than chalk, see benchmarks
- only 3 KB dist code
- standard API like chalk
- default import
import ansis from 'ansis'
, usageansis.red('error')
- named import
import { red } from 'ansis'
, usagered('error')
- chained syntax
red.bold.underline('text')
- nested template strings
red`R ${green`G`} R`
- ANSI 256 colors and Truecolor (RGB, HEX)
rgb(224, 17, 95)`Ruby`
,hex('#96C')`Amethyst`
- extending of base colors with named truecolors
- ANSI codes as
open
andclose
property for each style`Hello ${red.open}World${red.close}!`
- strip ANSI codes method
ansis.strip()
- correct style break at the
end of line
when used\n
in string - supports the environment variables
NO_COLOR
FORCE_COLOR
and flags--no-color
--color
- auto detects color support
- TypeScript friendly
- zero dependencies
If you have discovered a bug or have a feature suggestion, feel free to create an issue on GitHub.
npm install ansis
You can import default module or named colors with ESM or CommonJS syntax.
// ESM default import
import ansis from 'ansis';
// ESM named import
import { red, green, blue } from 'ansis';
// CommonJS default import
const ansis = require('ansis');
// CommonJS named import
const { red, green, blue } = require('ansis');
console.log(ansis.green('Success!'));
console.log(green('Success!'));
// template string
console.log(green`Success!`);
// chained syntax
console.log(green.bold`Success!`);
// nested syntax
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!`}`);
The ansis
supports both the default import
and named import
.
// default import
import ansis from 'ansis';
ansis.red.bold('text');
You can import named colors, styles and functions. All imported colors and styles are chainable
.
// named import
import { red, hex, italic } from 'ansis';
red.bold('text');
Default import and named import can be combined.
// default and named import
import ansis, { red } from 'ansis';
const redText = red('text'); // colorized ANSI string
const text = ansis.strip(redText); // pure string without ANSI codes
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`;
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`;
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`);
// deep nested chained styles
green(
`green ${yellow(
`yellow ${magenta(
`magenta ${cyan(
`cyan ${red.italic.underline`red italic underline`} cyan`,
)} magenta`,
)} yellow`,
)} green`,
);
Multiline nested template strings:
import { red, green, hex, visible, inverse } from 'ansis';
// defined a truecolor as the constant
const orange = hex('#FFAB40');
let cpu = 33;
let ram = 44;
let disk = 55;
// normal colors
visible`
CPU: ${red`${cpu}%`}
RAM: ${green`${ram}%`}
DISK: ${orange`${disk}%`}
`;
// inversed colors
inverse`
CPU: ${red`${cpu}%`}
RAM: ${green`${ram}%`}
DISK: ${orange`${disk}%`}
`;
Colors and styles have standard names used by many popular libraries, such as chalk, colorette, kleur.
Foreground colors | Background colors | Styles |
---|---|---|
black |
bgBlack |
dim (aliasfaint ) |
red |
bgRed |
bold |
green |
bgGreen |
italic |
yellow |
bgYellow |
underline |
blue |
bgBlue |
strikethrough strike ) |
magenta |
bgMagenta |
doubleUnderline (not widely supported) |
cyan |
bgCyan |
overline (not widely supported) |
white |
bgWhite |
frame (not widely supported) |
gray (alias grey ) |
bgGray |
encircle (not widely supported) |
blackBright |
bgBlackBright |
inverse |
redBright |
bgRedBright |
visible |
greenBright |
bgGreenBright |
hidden |
yellowBright |
bgYellowBright |
reset |
blueBright |
bgBlueBright |
|
magentaBright |
bgMagentaBright |
|
cyanBright |
bgCyanBright |
|
whiteBright |
bgWhiteBright |
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';
// extend base colors
ansis.extend({
pink: '#FF75D1',
orange: '#FFAB40',
});
// the custom colors are available under namespace `ansis`
ansis.pink('text');
ansis.orange('text');
Usage example with TypeScript:
import ansis, { AnsiColorsExtend } from 'ansis';
// extend base colors
ansis.extend({
pink: '#FF75D1',
orange: '#FFAB40',
});
const write = (style: AnsiColorsExtend<'pink' | 'orange'>, message: string) => {
console.log(ansis[style](message));
}
write('red', 'message'); // base color OK
write('pink', 'message'); // extended color OK
write('orange', 'message'); // extended color OK
write('unknown', 'message'); // TypeScript Error
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()
andbgAnsi256()
methods are implemented for compatibility with thechalk
API.
See ANSI color codes.
import { bold, ansi256, fg, bgAnsi256, bg } from 'ansis';
// foreground color
ansi256(96)`Bright Cyan`;
fg(96)`Bright Cyan`;
// background color
bgAnsi256(105)`Bright Magenta`;
bg(105)`Bright Magenta`;
// function is chainable
ansi256(96).bold`bold Bright Cyan`;
// function is avaliable in each style
bold.ansi256(96).underline`bold underline Bright Cyan`;
// you can combine the functions and styles in any order
bgAnsi256(105).ansi256(96)`cyan text on magenta background`
bg(105).fg(96)`cyan text on magenta background`
You can use the hex
or rgb
format.
Foreground function: hex()
rgb()
Background function: bgHex()
bgRgb()
import { bold, hex, rgb, bgHex, bgRgb } from 'ansis';
// foreground color
hex('#E0115F').bold`bold Ruby`;
hex('#96C')`Amethyst`;
rgb(224, 17, 95).italic`italic Ruby`;
// background color
bgHex('#E0115F')`Ruby`;
bgHex('#96C')`Amethyst`;
bgRgb(224, 17, 95)`Ruby`;
// you can combine the functions and styles in any order
bold.hex('#E0115F').bgHex('#96C')`ruby bold text on amethyst background`
You can use the ANSI escape codes with open
and close
properties for each style.
import { red, bold } from 'ansis';
// each style has `open` and `close` properties
console.log(`Hello ${red.open}ANSI${red.close} World!`);
// you can defiene own style which will have the `open` and `close` properties
const myStyle = bold.italic.black.bgHex('#E0115F');
console.log(`Hello ${myStyle.open}ANSI${myStyle.close} World!`);
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.
Supports correct style break at the end of line
.
import { bgGreen } from 'ansis';
console.log(bgGreen`\nAnsis\nNew Line\nNext New Line\n`);
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');
Defaults, the output in terminal console is colored and output in a file is uncolored.
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
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.
Library ______________ - name - code size - named import |
Naming colors | ANSI 256 colors |
True- color |
Chained syntax |
Nested template strings |
New Line |
Supports CLI params |
---|---|---|---|---|---|---|---|
colors.js 18.1KB β named import |
non-standard16 colors |
β | β | β | β | β | onlyFORCE_COLOR --no-color --color |
colors-cli 8.6KB β named import |
non-standard16 colors |
β | β | β | β | β | only--no-color --color |
cli-color β named import |
standard16 colors |
β | β | β | β | β | onlyNO_COLOR |
ansi-colors 5.8KB β named import |
standard16 colors |
β | β | β | β | β | onlyFORCE_COLOR |
colorette 3.3KB β
named import |
standard16 colors |
β | β | β | β | β | NO_COLOR FORCE_COLOR --no-color --color |
picocolors 2.6KB β named import |
standard8 colors |
β | β | β | β | β | NO_COLOR FORCE_COLOR --no-color --color |
kleur 2.7KB β
named import |
standard8 colors |
β | β | β | β | β | onlyNO_COLOR FORCE_COLOR |
chalk 15KB β named import |
standard16 colors |
β | β | β | β | β | NO_COLOR FORCE_COLOR --no-color --color |
ansis 3.2KB β
named import |
standard16 colors |
β | β | β | β | β | NO_COLOR FORCE_COLOR --no-color --color |
Note
Code size
The size of distributed code that will be loaded viarequire
orimport
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:
colors-cli
:x<n>
cli-color
:xterm(n)
chalk
:ansi256(n)
bgAnsi256(n)
ansis
:ansi256(n)
bgAnsi256(n)
fg(n)
bg(n)
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 atend-of-line
.lib.bgGreen(`First Line Next Line`);
git clone https://github.com/webdiscus/ansis.git
cd ./ansis
npm i
npm run demo
git clone https://github.com/webdiscus/ansis.git
cd ./ansis
npm i
npm run bench
MacBook Pro 16" M1 Max 64GB
macOS Monterey 12.1
Node.js v16.13.1
TerminaliTerm2
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,669,734 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
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
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)
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
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
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
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)
npm run test
will run the unit and integration tests.
npm run test:coverage
will run the tests with coverage.
Most popular ANSI libraries for Node.js
: