Plate 26
Picocolors vs Chalk: 1.0 KB vs 3.4 KB Gzip
Aditya Challa4 min read
I bundled the color APIs on this box: picocolors 1.1.1 came in at 1,035 B gzip against chalk 6.0.1 at 3,429 B. On a 200,000-call styled-string loop with FORCE_COLOR=1, picocolors ran about 9.4M ops/s and chalk about 4.2M.
Short answer: pick picocolors when you want the smallest ANSI dependency for a CLI or Vite plugin log line. Pick chalk when you already use nested chalk chains and want the wider chalk ecosystem. No affiliate links in this post.
What I tested
- Machine: 8 vCPU Intel Xeon / 15 GB RAM shared Linux cloud box, tested 6 Oct 2026 about 01:01–01:02 IST.
- Versions: picocolors 1.1.1, chalk 6.0.1, Node 22.20.0, esbuild 0.28.2 minify + gzip -9.
- Fixture: /workspace/bench-picocolors-chalk/. Size entries call red(bold), green, yellow, and cyan once each. Speed: same four styles concatenated, 200,000 iters × 9 rounds (median) after warm, with FORCE_COLOR=1 so both emit ANSI.
- Findings: node gzip 1,035 B vs 3,429 B; browser build 654 B vs 2,645 B. Median speed 21.274 ms vs 47.593 ms for 200k calls (about 9.40M vs 4.20M ops/s). Disk trees about 32 KB vs 108 KB.
- One surprise: with colors forced on, chalk was about 2.2× slower on this simple nest, not only larger. The gap is size-first, but the loop is not free either.
- Not tested: chalk nested template literals, chalk Level 3 truecolor, Windows terminals, browser CSS color helpers, TypeScript types surface, or chalk's full chain API beyond four styles.
How wide was the size gap?
| Build (esbuild minify) | Minified | gzip -9 |
|---|---|---|
| picocolors (node) | 2,664 B | 1,035 B |
| chalk 6 (node) | 8,077 B | 3,429 B |
| picocolors (browser) | 1,286 B | 654 B |
| chalk 6 (browser) | 6,345 B | 2,645 B |
picocolors was about 3.3× smaller gzip on the node entry and about 4.0× smaller on the browser entry. Track shipped weight with size-limit vs bundlesize. After a swap, prune unused imports with knip vs depcheck.
How fast were the styled strings?
| Path (200,000 calls, median of 9, FORCE_COLOR=1) | picocolors | chalk |
|---|---|---|
| red(bold)+green+yellow+cyan | 21.274 ms (9.40M/s) | 47.593 ms (4.20M/s) |
On this box picocolors was roughly 2.2× faster on the nested style path. Formatters sit next to my dprint vs Prettier notes when I care about CLI output tooling, not page CSS.
Which one should you pick?
| Situation | My pick |
|---|---|
| Vite / Rollup plugin that logs a few lines | picocolors |
| New CLI where every KB of deps matters | picocolors |
| App already deep in chalk chains | chalk |
| You need chalk's Level API / truecolor helpers | chalk |
| Bundle budget under about 1.5 KB gzip for colors | picocolors |
Bottom line: picocolors 1.1.1 shipped 1.0 KB gzip against chalk 6.0.1 at 3.4 KB, and ran about 9.4M ops/s against 4.2M on a 200k styled-string fixture. Who should not switch: teams with a large chalk-colored codebase — rewrite cost beats a 2.4 KB gzip win. Lint the swap with Biome vs ESLint/Prettier. Test runner: Jest vs Vitest.
How this was made: I installed picocolors and chalk on the ShopperCove box, measured esbuild minify+gzip sizes (node and browser), timed FORCE_COLOR styled-string loops, and recorded the JSON. The write-up was drafted with AI help and checked against that output.
Sources
- https://github.com/alexeyraspopov/picocolors
- https://www.npmjs.com/package/picocolors
- https://github.com/chalk/chalk
- https://www.npmjs.com/package/chalk
Related
- https://www.shoppercove.com/blog/size-limit-vs-bundlesize
- https://www.shoppercove.com/blog/knip-vs-depcheck
- https://www.shoppercove.com/blog/dprint-vs-prettier
- https://www.shoppercove.com/blog/jest-vs-vitest
- https://www.shoppercove.com/blog/biome-vs-eslint-prettier
- https://www.shoppercove.com/blog/oxlint-vs-eslint
- https://www.shoppercove.com/blog/lefthook-vs-husky
- https://www.shoppercove.com/blog/pnpm-vs-npm-vs-bun
Lab evidence
What I found running this
Hands-on on ShopperCove box 6 Oct 2026 ~01:01-01:02 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 22.20.0). picocolors 1.1.1 vs chalk 6.0.1, esbuild 0.28.2. Fixture /workspace/bench-picocolors-chalk/: entries call red(bold)+green+yellow+cyan. Size: node + browser platforms, minify + gzip -9. Speed: FORCE_COLOR=1 dynamic import, 200,000 styled concatenations x 9 rounds (median) after warm. Medians: node gzip 1,035 vs 3,429 B; browser 654 vs 2,645 B; speed 21.274 vs 47.593 ms (9.40M vs 4.20M ops/s). Disk ~32 KB vs ~108 KB. Raw: res-bundle.json, res-speed.json. Not tested: chalk Level/truecolor, nested template literals, Windows terminals, browser CSS helpers. No affiliate.
Related links
Plate 75
Turbo vs Lage: 1.97s vs 3.01s Cold Build
Turbo 2.11.7 vs Lage 2.17.0 on a 4-package diamond npm workspace (250k-iter build scripts): cold wall medians 1,974 ms vs 3,007 ms (~1.5x); Turbo warm 4/4 cache hits ~0.50 s; Lage warm ~1.49 s. Lage required git init.
5 Oct 2026
Plate 17
Immer vs Mutative: 86 us vs 3 us per Update
5 Oct 2026
Plate 93
Nanostores vs Jotai: 1.3 KB vs 2.7 KB Gzip
5 Oct 2026