The ansis use the SGR (Select Graphic Rendition) codes defined in the ECMA-48 standard.
Why yet one lib?
Fastest, small, full standard ANSI colors & styles, truecolor, chainable, nestable, template literals.
See comparison of most popular ANSI colors libraries and benchmark.
- supports both ESM and CommonJS
- up to x3.5 faster than chalk, see benchmarks
- dist code is 3 KB only
- standard API compatible with many popular ANSI color libraries like chalk
- named import of styles & colors
import { red, blue, bold } from 'ansis/colors'
- supports chained
red.bold('text')
syntax - supports nested template literals
red`A ${cyan`B`} A`
- ANSI 256 colors and Truecolor (RGB, HEX)
- supports extending of base colors with named custom truecolor
- auto detects color support
- supports the environment variables
NO_COLOR
FORCE_COLOR
and flags--no-color
--color
- supports removing ANSI color codes from string (strip ANSI codes)
- TypeScript friendly
- zero dependency
npm install ansis
import { black, red, cyan, inverse, reset } from 'ansis/colors'; // named import
import ansis from 'ansis'; // ESM
const ansis = require('ansis'); // CommonJS
console.log(ansis.green`Hello ${inverse`ANSI`} World!`);
console.log(black.bgYellow`Warning:${reset.cyan` /path/to/file.js`} ${red`not found!`}`);
You can import named colors, styles and functions. All imported colors and styles are chainable.
Note
Imported code is not treeshakeable.
Don't worry, full functional code is3KB
only.
import { red, green, blue, yellow, hex, bold, italic } from 'ansis/colors';
red.bold('text');
italic.underline.cyan('text');
hex('#FF75D1').bgCyan.bold('text');
import ansis from 'ansis';
import { red, italic, underline } from 'ansis/colors';
// with namespace
ansis.red('text');
ansis.cyan.italic('text');
ansis.blau.underline.bold('text');
// with named import
red.italic.bold('text');
italic.bold.red('text');
underline.yellowBright('text');
import { white, cyan, green } from 'ansis/colors';
white(`MakBookPro, ${cyan.bold(`RAM:`)} 64 GB | ${green.bold(`GPU:`)} 32 cores`);
Template literals allow you to make a complex template more readable and shorter.
None of the existing libraries (chalk, kleur, colorette, colors.js etc.) support nested template strings.
This does it only one library - ansis
. Use it and enjoy!
// import used standard styles, colors and functions
import { white, red, green, yellow, cyan, bold, visible, hex } from 'ansis/colors';
// define custom colors
const pink = hex('#FF75D1');
const orange = hex('#FFAB40');
// template string
red`text`;
pink`text`;
orange`text`;
// chained
red.bold`text`;
bold.yellowBright`text`;
hex('#FF75D1').bgYellow.bold`text`;
// nested
white`MakBookPro, ${cyan.bold`RAM:`} 64 GB | ${green.bold`GPU:`} 32 cores`;
white`MakBookPro, ${cyan.bold`RAM: ${yellow`64`} GB`} | ${green.bold`GPU: ${yellow`32`} cores`}`;
// mutiline nested
visible`
CPU: ${red.bold`${33}%`}
RAM: ${green`${44}%`}
DISK: ${hex('#FFAB40')`${55}%`}
`;
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 extends 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: .ansi(code)
has aliases .ansi256(code)
and .fg(code)
Background function: .bgAnsi(code)
has aliases .ansi256(code)
and .bg(code)
See ANSI color codes.
// foreground color
ansis.ansi(96).bold('bold Bright Cyan');
ansis.ansi256(96).bold('bold Bright Cyan'); // `ansi256` is the alias for `ansi`
ansis.fg(96).bold('bold Bright Cyan'); // `fg` is the short alias for `ansi`
// background color
ansis.bgAnsi(105)('Bright Magenta');
ansis.bgAnsi256(105)('Bright Magenta'); // `bgAnsi256` is the alias for `bgAnsi`
ansis.bg(105)('Bright Magenta'); // `bg` is the short alias for `bgAnsi`
The
ansi256()
andbgAnsi256()
methods are implemented for compatibility with thechalk
API.
Foreground: hex
rgb
Background: bgHex
bgRgb
// foreground color
ansis.hex('#E0115F').bold('bold Ruby');
ansis.hex('#96C')('Amethyst');
ansis.rgb(224, 17, 95).italic.underline('italic underline Ruby');
// background color
ansis.bgHex('#E0115F')('Ruby');
ansis.bgHex('#96C')('Amethyst');
ansis.bgRgb(224, 17, 95)('Ruby');
Define your own themes:
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');
You can use the open
and close
properties for each style.
const myStyle = ansis.bold.italic.black.bgHex('#ABCDEF');
console.log(`Hello ${myStyle.open}ANSI${myStyle.close} World!`);
Supports correct style break at the end of line
.
ansis.bgGreen(`\nAnsis\nNew Line\nNext New Line\n`);
The Ansis class contains one method strip()
to remove all ANSI codes from string.
import ansis from 'ansis';
const ansiString = ansis.green(`Hello ${ansis.inverse('ANSI')} World!`);
const string = ansis.strip(ansiString);
The variable string
will contain the pure string Hello ANSI World!
.
Defaults, the output in terminal console is colored and output in a file is uncolored.
example.js
import ansis from 'ansis';
console.log(ansis.red`COLOR`);
$ node example.js #=> color
$ node example.js > log.txt #=> no color
To force disable or enable colored output use environment variables NO_COLOR
and FORCE_COLOR
.
$ NO_COLOR=1 node example.js #=> force disable colors
$ FORCE_COLOR=0 node example.js #=> force disable colors
$ FORCE_COLOR=1 node example.js > log.txt #=> force enable colors
Note
The
NO_COLOR
variable should be presents with any not empty value. The value is not important, see standard description by NO_COLOR.
NO_COLOR=1
NO_COLOR=true
disable colorsThe
FORCE_COLOR
variable should be presents with one of values:
FORCE_COLOR=0
force disable colors
FORCE_COLOR=1
force enable colors
If you have an executable script.
example.js
#!/usr/bin/env node
import ansis from 'ansis';
console.log(ansis.red`COLOR`);
Use arguments --no-color
or --color=false
to disable colors and --color
to enable ones.
$ ./example.js #=> color
$ ./example.js --no-color #=> no color
$ ./example.js --color=false #=> no color
$ ./example.js > log.txt #=> no color
$ ./example.js --color > log.txt #=> color
$ ./example.js --color=true > log.txt #=> color
Library | Naming of base colors |
Chained syntax |
Nested template strings |
New Line |
ANSI 256 colors methods |
Truecolor methods |
Supports CLI params |
---|---|---|---|---|---|---|---|
colors.js code size 18.1KB |
non-standard, e.g. brightRed (16 colors)❌ named import |
✅ | ❌ | ✅ | ❌ | ❌ | onlyFORCE_COLOR --no-color --color |
colorette code size 3.3KB |
standard (16 colors) âś… named import |
❌ | ❌ | ❌ | ❌ | ❌ | NO_COLOR FORCE_COLOR --no-color --color |
picocolors code size 2.6KB |
standard (8 colors) ❌ named import |
❌ | ❌ | ❌ | ❌ | ❌ | NO_COLOR FORCE_COLOR --no-color --color |
cli-color |
standard (16 colors) ❌ named import |
✅ | ❌ | ❌ | xterm(n) |
❌ | onlyNO_COLOR |
colors-cli code size 8.6KB |
non-standard, e.g. red_bbt (16 colors) ❌ named import |
✅ | ❌ | ✅ | x<n> |
❌ | only--no-color --color |
ansi-colors code size 5.8KB |
standard (16 colors) ❌ named import |
✅ | ❌ | ✅ | ❌ | ❌ | onlyFORCE_COLOR |
kleur code size 2.7KB |
standard (8 colors) âś… named import |
✅ | ❌ | ❌ | ❌ | ❌ | onlyNO_COLOR FORCE_COLOR |
chalk code size 15KB |
standard (16 colors) ❌ named import |
✅ | ❌ | ✅ | ansi256(n) bgAnsi256(n) |
hex() rgb() |
NO_COLOR FORCE_COLOR --no-color --color |
ansis code size 3.2KB |
standard (16 colors) âś… named import |
âś… | âś… | âś… | ansi256(n) bgAnsi256(n) fg(n) bg(n) |
hex() rgb() |
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
import { red, green, blue } from 'lib/colors';
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/bench
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`);
colors.js 1,158,572 ops/sec
colorette 4,572,582 ops/sec
picocolors 3,841,124 ops/sec
cli-color 470,320 ops/sec
colors-cli 109,811 ops/sec
ansi-colors 1,265,615 ops/sec
kleur/colors 2,281,415 ops/sec
kleur 2,228,639 ops/sec
chalk 2,287,146 ops/sec
+ ansis 2,669,734 ops/sec
const colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'];
colors.forEach((color) => c[color]('foo'));
colors.js 640,101 ops/sec
colorette 1,874,506 ops/sec
picocolors 8,265,628 ops/sec
cli-color 305,690 ops/sec
colors-cli 104,962 ops/sec
ansi-colors 1,010,628 ops/sec
kleur/colors 2,074,111 ops/sec
kleur 5,455,121 ops/sec
chalk 4,428,884 ops/sec
+ ansis 6,197,754 ops/sec
colors.forEach((color) => c[color].bold.underline.italic('foo'));
colors.js 138,219 ops/sec
colorette (not supported)
picocolors (not supported)
cli-color 144,837 ops/sec
colors-cli 52,732 ops/sec
ansi-colors 158,921 ops/sec
kleur/colors (not supported)
kleur 514,035 ops/sec
chalk 1,234,573 ops/sec
+ ansis 5,515,868 ops/sec
colors.forEach((color) => c[color](c.bold(c.underline(c.italic('foo')))));
colors.js 166,425 ops/sec
colorette 695,350 ops/sec
picocolors 942,592 ops/sec
cli-color 65,561 ops/sec
colors-cli 13,800 ops/sec
ansi-colors 260,316 ops/sec
kleur/colors 561,111 ops/sec
kleur 648,195 ops/sec
chalk 497,292 ops/sec
+ ansis 558,575 ops/sec
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.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.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.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.magenta('magenta')} red ${c.red('red')} red ${c.red(
'red')} red ${c.cyan('cyan')} 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.red('red')} red ${c.red(
'red')} red ${c.red('red')} message`);
colors.js 89,633 ops/sec
colorette 243,139 ops/sec
picocolors 243,975 ops/sec
cli-color 41,657 ops/sec
colors-cli 14,264 ops/sec
ansi-colors 121,451 ops/sec
kleur/colors 234,132 ops/sec
kleur 221,446 ops/sec
chalk 189,960 ops/sec
+ ansis 211,868 ops/sec
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`
);
colors.js 451,592 ops/sec
colorette 1,131,757 ops/sec
picocolors 1,002,649 ops/sec
cli-color 213,441 ops/sec
colors-cli 40,340 ops/sec
ansi-colors 362,733 ops/sec
kleur/colors 478,547 ops/sec
kleur 464,004 ops/sec
chalk 565,965 ops/sec
+ ansis 882,220 ops/sec
Only two libraries support truecolors methods: ansis
and chalk
c.hex('#FBA')('foo');
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)
chalk 2,891,684 ops/sec
+ ansis 4,944,572 ops/sec
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
: