@prantlf/picocolors
v1.6.0
Published
The tiniest and the fastest library for terminal output formatting with ANSI colors
Maintainers
Readme
@prantlf/picocolors
The tiniest and the fastest library for terminal output formatting with ANSI colors.
import pc from "@prantlf/picocolors"
console.log(
pc.green(`How are ${pc.italic(`you`)} doing?`)
)- No dependencies.
- 14 times smaller and 2 times faster than chalk.
- Used by popular tools like PostCSS, SVGO, Stylelint, and Browserslist.
- Node.js v6+ & browsers support. Support for both CJS and ESM projects.
- TypeScript type declarations included.
NO_COLORfriendly.
This is a fork of the original project with the following changes:
- Include native ESM output, which allows named imports #60.
- Add benchmarks for
chalk5 andyoctocolors#61. - Add benchmarks for
chalk6 andstyleText. - Include support for
overline. - Include support for
underlineDouble,underlineCurly,underlineDottedandunderlineDashed. - Include additional UMD output.
- Support browsers with the Blink core.
Motivation
With picocolors we are trying to draw attention to the node_modules size
problem and promote performance-first culture.
Prior Art
Credits go to the following projects:
- Nanocolors by @ai
- Colorette by @jorgebucaran
- Kleur by @lukeed
- Colors.js by @Marak
- Chalk by @sindresorhus
Benchmarks
Versions of the benchmarked libraries:
$ node versions.js
ansi-colors 4.1.3
chalk4 4.1.2
chalk5 5.6.2
chalk6 6.0.0
cli-color 2.0.4
colorette 2.0.20
kleur 4.1.5
nanocolors 0.2.13
yoctocolors 2.2.0
picocolors-upstream 1.1.1
picocolors-fork 1.4.0The space in node_modules including sub-dependencies (bundling the default export):
$ node size.mjs
┌─────────────────────┬───────────┐
│ (index) │ size (KB) │
├─────────────────────┼───────────┤
│ picocolors-fork │ 5.18 │
│ picocolors-upstream │ 5.07 │
│ colorette │ 6.08 │
│ chalk v4 │ 50.02 │
│ chalk v5 │ 17.02 │
│ chalk v6 │ 19.48 │
│ kleur │ 3.84 │
│ kleur/colors │ 3.1 │
│ ansi-colors │ 10.37 │
│ cli-color │ 148.61 │
│ nanocolors │ 5.79 │
│ yoctocolors │ 8.88 │
└─────────────────────┴───────────┘Library loading time (CJS):
$ node loading.js
Results for CJS:
chalk6 1.805 ms
chalk5 0.673 ms
chalk4 1.625 ms
cli-color 10.201 ms
ansi-colors 0.599 ms
kleur 0.616 ms
kleur/colors 0.395 ms
colorette 0.338 ms
nanocolors 0.238 ms
yoctocolors 0.424 ms
picocolors-upstream 0.206 ms
+ picocolors-fork 0.138 msLibrary loading time (ESM):
$ node loading.js --esm
Results for ESM:
chalk6 2.003 ms
chalk5 1.044 ms
chalk4 1.643 ms
cli-color 10.657 ms
ansi-colors 0.738 ms
kleur 0.528 ms
kleur/colors 0.413 ms
colorette 0.400 ms
nanocolors 0.272 ms
yoctocolors 0.619 ms
picocolors-upstream 0.314 ms
+ picocolors-fork 0.212 msBenchmark for simple use case (CJS):
$ node simple.js
chalk6 64,078,194 ops/sec
chalk5 64,745,903 ops/sec
chalk4 64,304,541 ops/sec
cli-color 5,053,268 ops/sec
ansi-colors 15,287,637 ops/sec
kleur 75,415,733 ops/sec
kleur/colors 115,295,918 ops/sec
colorette 113,700,407 ops/sec
nanocolors 115,771,312 ops/sec
yoctocolors 112,113,428 ops/sec
styleText 1,013,681 ops/sec
picocolors-upstream 114,758,036 ops/sec
+ picocolors-fork 114,577,731 ops/secBenchmark for simple use case (ESM):
$ node simple.mjs --expose-gc
benchmark avg (min … max) p75 / p99 (min … top 1%)
------------------------------------------- -------------------------------
chalk v4 7.79 ns/iter 7.93 ns █▄
(6.77 ns … 35.16 ns) 12.97 ns ███▇
( 6.16 b … 278.17 b) 32.22 b █████▆▂▂▂▂▂▂▂▁▁▁▁▁▁▁▁
chalk v5 4.85 ns/iter 4.88 ns ▂█
(4.38 ns … 44.27 ns) 7.69 ns ▂███
( 16.10 b … 213.12 b) 16.23 b ████▄▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁
chalk v6 7.74 ns/iter 7.89 ns █
(6.61 ns … 27.38 ns) 11.35 ns █▅
( 25.10 b … 193.12 b) 32.22 b ▃▇▄▆███▂▂▂▂▂▁▁▁▁▁▁▁▁▁
cli-color 192.35 ns/iter 194.65 ns ▆██▄
(184.65 ns … 248.62 ns) 207.17 ns ▂▅█████▆▆▃
(343.75 b … 966.02 b) 561.25 b ▂███████████▇▆▅▂▂▂▃▁▁
ansi-colors 61.94 ns/iter 62.75 ns ▅▅█▄
(56.96 ns … 267.66 ns) 77.03 ns █████▃
( 4.78 b … 469.13 b) 256.13 b ▄███████▅▃▃▃▃▃▂▂▂▂▁▁▁
kleur 7.58 ns/iter 7.60 ns █
(7.02 ns … 22.43 ns) 11.13 ns █▇▄
( 13.97 b … 181.62 b) 32.24 b ▆███▅▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
kleur/colors 4.60 ns/iter 4.62 ns █
(4.38 ns … 14.17 ns) 7.42 ns █
( 0.10 b … 104.10 b) 0.20 b ███▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
colorette 1.20 ns/iter 1.20 ns █▅ ▂
(1.13 ns … 15.93 ns) 1.60 ns ██ █
( 0.10 b … 146.54 b) 0.12 b ██▂█▅▂▂▄▁▁▁▁▁▁▁▁▁▁▁▁▁
nanocolors 1.19 ns/iter 1.16 ns █
(1.13 ns … 16.47 ns) 2.26 ns █
( 0.10 b … 143.51 b) 0.12 b █▅▄▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
yoctocolors 1.23 ns/iter 1.21 ns █▄
(1.13 ns … 44.24 ns) 2.85 ns ██
( 0.10 b … 160.45 b) 0.12 b ██▄▁▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
styleText 1.09 µs/iter 1.12 µs █ ▄
(1.03 µs … 1.19 µs) 1.17 µs ▃▃▂█▆█▅▇ ▇▃ ▂
(174.62 b … 467.41 b) 186.54 b ▆▆██████████████▅▅▁▄▇
picocolors-upstream 1.31 ns/iter 1.29 ns █
(1.18 ns … 13.02 ns) 3.13 ns ▅█
( 0.10 b … 136.31 b) 0.12 b ██▅▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
picocolors-fork 1.27 ns/iter 1.26 ns █▆
(1.18 ns … 16.76 ns) 2.51 ns ██
( 0.10 b … 136.28 b) 0.13 b ██▇▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
┌ ┐
┬
chalk v4 │
┴
┬
chalk v5 │
┴
┬
chalk v6 │
┴
┬╷
cli-color │┤
┴╵
┬╷
ansi-colors │┤
┴╵
┬
kleur │
┴
┬
kleur/colors │
┴
┬
colorette │
┴
┬
nanocolors │
┴
┬
yoctocolors │
┴
╷ ┌┬┐ ╷
styleText ├─┤│├─┤
╵ └┴┘ ╵
┬
picocolors-upstream │
┴
┬
picocolors-fork │
┴
└ ┘
1.13 ns 586.48 ns 1.17 µsBenchmark for complex use cases (CJS):
$ node complex.js
chalk6 3,978,645 ops/sec
chalk5 3,896,253 ops/sec
chalk4 4,033,711 ops/sec
cli-color 547,413 ops/sec
ansi-colors 1,497,581 ops/sec
kleur 4,450,128 ops/sec
kleur/colors 5,429,638 ops/sec
colorette 6,240,239 ops/sec
nanocolors 6,152,210 ops/sec
yoctocolors 6,229,059 ops/sec
styleText 128,642 ops/sec
picocolors-upstream 9,740,011 ops/sec
+ picocolors-fork 9,697,985 ops/secBenchmark for complex use cases (ESM):
$ node complex.mjs --expose-gc
benchmark avg (min … max) p75 / p99 (min … top 1%)
------------------------------------------- -------------------------------
chalk v4 262.08 ns/iter 255.71 ns ▇█
(228.12 ns … 452.96 ns) 372.69 ns ██
( 1.16 kb … 1.36 kb) 1.17 kb ▂████▂▁▁▂▂▂▂▄▂▄▂▂▂▁▁▁
chalk v5 264.75 ns/iter 263.04 ns ▇█
(239.14 ns … 388.98 ns) 375.09 ns ██▃
( 1.07 kb … 1.74 kb) 1.17 kb ▂████▃▂▁▁▁▁▁▁▁▁▁▂▂▂▂▁
chalk v6 260.12 ns/iter 257.61 ns █
(231.21 ns … 464.40 ns) 364.47 ns ▃█▇
( 1.01 kb … 1.68 kb) 1.17 kb ▁▄███▃▁▁▁▁▁▁▁▁▁▁▂▂▂▂▁
yoctocolors 165.38 ns/iter 164.40 ns █
(148.42 ns … 304.20 ns) 229.49 ns ▇██
(728.56 b … 1.16 kb) 1.01 kb ▁▅███▅▁▁▁▁▁▁▁▁▁▁▁▂▂▂▁
styleText 9.49 µs/iter 9.50 µs █
(9.41 µs … 9.63 µs) 9.57 µs █ █ █ █
( 1.79 kb … 1.92 kb) 1.91 kb █▁▁█▁█▁▁▁████▁▁▁█▁▁▁█
cli-color 1.97 µs/iter 2.03 µs █▆▄
(1.89 µs … 2.11 µs) 2.10 µs ▃ ███▆ ▃ ▆
( 5.07 kb … 5.11 kb) 5.08 kb ▅████████▅▁▃▃▃█▇█▇▃▃▇
ansi-colors 741.28 ns/iter 742.26 ns ██▇▃
(685.80 ns … 1.04 µs) 901.48 ns ▅████▃
( 2.39 kb … 2.69 kb) 2.54 kb ▃██████▂▁▁▁▁▂▂▃▃▄▃▃▃▂
kleur 240.14 ns/iter 236.96 ns █▃
(217.03 ns … 362.44 ns) 350.23 ns ██
(897.18 b … 1.43 kb) 1.18 kb ▂███▅▂▁▁▁▁▁▁▁▁▁▁▂▂▂▂▁
kleur/colors 199.21 ns/iter 197.11 ns ▄█
(178.80 ns … 315.07 ns) 296.04 ns ██
(808.86 b … 1.24 kb) 1.04 kb ▂███▅▁▁▁▁▁▁▁▁▁▁▁▁▁▂▂▁
colorette 167.65 ns/iter 165.55 ns █▃
(148.17 ns … 287.55 ns) 268.02 ns ▂██
(825.18 b … 1.19 kb) 1.04 kb ▂███▄▁▁▁▁▁▁▁▁▁▁▁▂▂▂▁▁
nanocolors 168.80 ns/iter 168.84 ns █▂
(150.64 ns … 246.28 ns) 236.43 ns ▇██
(789.10 b … 1.15 kb) 1.01 kb ▂▅████▄▂▁▁▁▁▁▁▁▁▁▂▂▂▁
picocolors-upstream 103.84 ns/iter 103.28 ns █
(90.95 ns … 200.90 ns) 183.59 ns ▄█▆
(684.17 b … 1.13 kb) 697.15 b ▂███▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂▁
picocolors-fork 103.38 ns/iter 102.69 ns █
(90.05 ns … 197.15 ns) 179.88 ns ██
(592.26 b … 1.12 kb) 697.06 b ▂███▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂▁
summary
picocolors-fork
1x faster than picocolors-upstream
1.6x faster than yoctocolors
1.62x faster than colorette
1.63x faster than nanocolors
1.93x faster than kleur/colors
2.32x faster than kleur
2.52x faster than chalk v6
2.54x faster than chalk v4
2.56x faster than chalk v5
7.17x faster than ansi-colors
19.08x faster than cli-color
91.8x faster than styleTextUsage
Picocolors provides an object which includes a variety of text coloring and formatting functions:
import pc from "@prantlf/picocolors"The object includes following coloring functions: black, red, green, yellow, blue, magenta, cyan, white, gray.
console.log(`I see a ${pc.red("red door")} and I want it painted ${pc.black("black")}`)The object also includes following background color modifier functions: bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite and bright variants bgBlackBright, bgRedBright, bgGreenBright, bgYellowBright, bgBlueBright, bgMagentaBright, bgCyanBright, bgWhiteBright.
console.log(
pc.bgBlack(
pc.white(`Tom appeared on the sidewalk with a bucket of whitewash and a long-handled brush.`)
)
)Besides colors, the object includes following formatting functions: dim, bold, hidden, italic, underline, underlineDouble, underlineCurly, underlineDotted, underlineDashed, overline, strikethrough, reset, inverse and bright variants blackBright, redBright, greenBright, yellowBright, blueBright, magentaBright, cyanBright, whiteBright.
for (let task of tasks) {
console.log(`${pc.bold(task.name)} ${pc.dim(task.durationMs + "ms")}`)
}The library provides additional utilities to ensure the best results for the task:
isColorSupported— boolean, explicitly tells whether or not the colors or formatting appear on the screenimport pc from "@prantlf/picocolors" if (pc.isColorSupported) { console.log("Yay! This script can use colors and formatters") }createColors(enabled)— a function that returns a new API object with manually defined color support configurationimport pc from "@prantlf/picocolors" let { red, bgWhite } = pc.createColors(options.enableColors)
All functions from the exported object are available as named exports too:
import { red, green, bold, reset } from "@prantlf/picocolors"Replacing chalk
Replace package name in import:
- import chalk from 'chalk' + import pico from '@prantlf/picocolors'Replace variable:
- chalk.red(text) + pico.red(text)Replace chains to nested calls:
- chalk.red.bold(text) + pico.red(pico.bold(text))You can use
colorize-templateto replace chalk’s tagged template literal.+ import { createColorize } from 'colorize-template' + let colorize = createColorize(pico) - chalk.red.bold`full {yellow ${"text"}}` + colorize`{red.bold full {yellow ${"text"}}}`
