Benchmarks
Every number this project claims in public, measured — and the ones that are not measured, saying so.
Generated by npm run bench:page from the run of 2026-10-27 at commit 440f18f.
Do not edit by hand.
Published claims, settled
Every number this repository states in public, checked against the record that settles it. "Not met" and "unmeasured" are different outcomes and never collapse into each other: one says we measured and it is not true, the other says we have not measured.
| Claim | Target | Measured | Outcome |
|---|---|---|---|
| the engine's cold start stays within 1.55× of cac's, the lightest framework in the landscape (a downward-only ratchet; the ≤ 1 bar is not reachable, D-102) | <= 1.55 | 1.46 ratio | ✅ met |
| the core entry point is under 52 KB bundled | <= 53248 | 24,460 bytes | ✅ met |
burgee stays within 2.35× of cac alone in a user's bundle (a downward-only ratchet, lowered as it shrinks; ≤ 1 is not reachable, D-102) | <= 2.35 | 2.34 ratio | ✅ met |
burgee/commander stays within 1.42× of commander alone in a user's bundle (a downward-only ratchet, lowered as it shrinks; ≤ 1 is not reachable, D-102) | <= 1.42 | 1.417 ratio | ✅ met |
burgee/yargs is lighter in a user's bundle than yargs, the package it replaces | <= 1 | 0.975 ratio | ✅ met |
roundel/chalk is lighter in a user's bundle than chalk, the package it replaces | <= 1 | 0.599 ratio | ✅ met |
roundel/tokens is lighter in a user's bundle than picocolors, the package it replaces | <= 1 | 0.15 ratio | ✅ met |
roundel/colorette is lighter in a user's bundle than colorette, the package it replaces | <= 1 | 0.909 ratio | ✅ met |
roundel/kleur is lighter in a user's bundle than kleur, the package it replaces | <= 1 | 0.561 ratio | ✅ met |
roundel/kleur/colors is lighter in a user's bundle than kleur/colors, the package it replaces | <= 1 | 0.903 ratio | ✅ met |
roundel/supports-color is lighter in a user's bundle than supports-color, the package it replaces | <= 1 | 0.829 ratio | ✅ met |
roundel/yoctocolors is lighter in a user's bundle than yoctocolors, the package it replaces | <= 1 | 0.951 ratio | ✅ met |
flagstaff/ora is lighter in a user's bundle than ora, the package it replaces | <= 1 | 0.938 ratio | ✅ met |
flagstaff/boxen is lighter in a user's bundle than boxen, the package it replaces | <= 1 | 0.698 ratio | ✅ met |
flagstaff/cli-table3 is lighter in a user's bundle than cli-table3, the package it replaces | <= 1 | 0.705 ratio | ✅ met |
flagstaff/spinner is lighter in a user's bundle than ora, the package it replaces | <= 1 | 0.121 ratio | ✅ met |
flagstaff/box is lighter in a user's bundle than boxen, the package it replaces | <= 1 | 0.503 ratio | ✅ met |
flagstaff/table is lighter in a user's bundle than cli-table3, the package it replaces | <= 1 | 0.554 ratio | ✅ met |
flagstaff/log-update is lighter in a user's bundle than log-update, the package it replaces | <= 1 | 0.517 ratio | ✅ met |
linegauge is lighter in a user's bundle than string-width, the package it replaces | <= 1 | 0.939 ratio | ✅ met |
linegauge/wrap is lighter in a user's bundle than wrap-ansi, the package it replaces | <= 1 | 0.795 ratio | ✅ met |
linegauge/slice is lighter in a user's bundle than slice-ansi, the package it replaces | <= 1 | 0.78 ratio | ✅ met |
linegauge/strip is lighter in a user's bundle than strip-ansi, the package it replaces | <= 1 | 0.595 ratio | ✅ met |
paratext is lighter in a user's bundle than ansi-escapes, the package it replaces | <= 1 | 1.632 ratio | ❌ not met |
bellpull is lighter in a user's bundle than tinyexec, the package it replaces | <= 1 | 0.986 ratio | ✅ met |
seniority/lilconfig is lighter in a user's bundle than lilconfig, the package it replaces | <= 1 | 0.612 ratio | ✅ met |
seniority/dotenv is lighter in a user's bundle than dotenv, the package it replaces | <= 1 | 0.516 ratio | ✅ met |
seniority/cosmiconfig + seniority/find-up is lighter in a user's bundle than cosmiconfig + find-up, what it replaces | <= 1 | 0.154 ratio | ✅ met |
closeout/exit-hook is lighter in a user's bundle than exit-hook, the package it replaces | <= 1 | 0.96 ratio | ✅ met |
closeout/signal-exit is lighter in a user's bundle than signal-exit, the package it replaces | <= 1 | 0.93 ratio | ✅ met |
controlroom/ink + react + react-reconciler is lighter in a user's bundle than ink + react, what it replaces | <= 1 | 0.79 ratio | ✅ met |
controlroom is lighter in a user's bundle than ink, the package it replaces | <= 1 | 0.065 ratio | ✅ met |
examples/dashboard/dashboard.mjs is lighter in a user's bundle than examples/dashboard-ink/screen.mjs, what it replaces | <= 1 | 0.066 ratio | ✅ met |
seniority/cosmiconfig + seniority/find-up installs no more bytes than cosmiconfig + find-up | <= 1 | 0.119 ratio | ✅ met |
seniority/cosmiconfig + seniority/find-up installs no more packages than cosmiconfig + find-up | <= 1 | 0.1 ratio | ✅ met |
controlroom/ink + react + react-reconciler installs no more bytes than ink + react | <= 1 | 0.432 ratio | ✅ met |
controlroom/ink + react + react-reconciler installs no more packages than ink + react | <= 1 | 0.275 ratio | ✅ met |
importing controlroom/ink starts no slower than importing ink + react, as a same-run ratio | <= 1 | 0.4 ratio | ✅ met |
importing controlroom starts no slower than importing ink + react, as a same-run ratio | <= 1 | 0.163 ratio | ✅ met |
burgee is lighter in a user's bundle than cac plus the 3 packages a user of it installs to reach the same capability set | <= 1 | 0.25 ratio | ✅ met |
burgee/commander is lighter in a user's bundle than commander plus the 3 packages a user of it installs to reach the same capability set | <= 1 | 0.438 ratio | ✅ met |
burgee/yargs is lighter in a user's bundle than yargs plus the 3 packages a user of it installs to reach the same capability set | <= 1 | 0.548 ratio | ✅ met |
| commander's own test suite passes 1360 of 1360 against our entry point | >= 1360 | 1,360 tests | ✅ met |
| yargs's own test suite passes 816 of 816 against our entry point | >= 816 | 816 tests | ✅ met |
| chalk's own test suite passes 58 of 58 against our entry point | >= 58 | 59 tests | ✅ met |
| ora's own test suite passes 99 of 99 against our entry point | >= 99 | 99 tests | ✅ met |
| log-update's own test suite passes 99 of 99 against our entry point | >= 99 | 99 tests | ✅ met |
| boxen's own test suite passes 84 of 84 against our entry point | >= 84 | 213 tests | ✅ met |
| an agent spends at least 40% fewer tokens per task against a CLI that meets the floor | <= 0.6 | 0.747 ratio | ❌ not met |
| an agent takes at least 30% fewer turns per task against a CLI that meets the floor | <= 0.7 | 0.75 ratio | ❌ not met |
The two agent rows changed measure on 2026-10-09 (D-20261009-b1-totals-and-explain). This run settled them on the ratio of pooled medians, which commander's bimodal median turned into a coin flip. They are now settled on the tokens and turns each build spends summed over every task-run. Summed from this run's per-task detail, burgee ÷ commander is 0.692 for tokens (claim ≤ 0.6) and 0.703 for turns (claim ≤ 0.7). The first published run that carries the total records settles both rows here.
B2 — cold start
Spawned processes, not an in-process micro-benchmark: process time is what a user and an
agent actually pay, and excluding Node's own startup would flatter every row.
bare node is the floor row and most of every other number.
These milliseconds are a property of the machine that ran them — AMD EPYC 7763 64-Core Processor, 4 cores, linux/x64, Node v24.13.0, on CI — and are not comparable across machines. Nothing gates on them. What is gated and banded is the ratio below, taken between two spawns interleaved in the same run, which cancels the machine out.
| Variant | p50 ms | p95 ms | spawns |
|---|---|---|---|
bare node | 28.4 | 29.9 | 92 |
commander | 45.2 | 48.7 | 92 |
burgee/commander | 48.3 | 51.9 | 92 |
yargs | 107.0 | 111.4 | 92 |
burgee/yargs | 68.7 | 72.5 | 92 |
cac | 32.2 | 34.2 | 92 |
burgee | 47.1 | 50.3 | 92 |
picocolors | 31.8 | 33.3 | 92 |
roundel/tokens | 32.0 | 34.1 | 92 |
roundel/chalk | 34.5 | 36.3 | 92 |
ink + react | 345.8 | 358.9 | 92 |
controlroom/ink | 138.7 | 159.3 | 92 |
controlroom | 56.3 | 61.0 | 92 |
lilconfig | 34.5 | 36.1 | 92 |
seniority/lilconfig | 32.7 | 34.5 | 92 |
dotenv | 51.4 | 58.8 | 92 |
seniority/dotenv | 35.4 | 37.6 | 92 |
string-width | 61.5 | 63.5 | 92 |
linegauge | 34.9 | 36.6 | 92 |
exit-hook | 31.8 | 34.1 | 92 |
closeout/exit-hook | 31.1 | 33.1 | 92 |
signal-exit | 31.1 | 32.8 | 92 |
closeout/signal-exit | 32.3 | 34.9 | 92 |
| Ratio | p50 | p95 | gate |
|---|---|---|---|
| burgee/commander ÷ commander | 1.077× | 1.162× | ≤ 1.4 |
| burgee/yargs ÷ yargs | 0.643× | 0.680× | ≤ 0.95 |
| burgee ÷ cac | 1.460× | 1.565× | ≤ 1.55 |
| controlroom/ink ÷ ink + react | 0.400× | 0.457× | ≤ 1 |
| controlroom ÷ ink + react | 0.163× | 0.174× | ≤ 1 |
| Difference | p50 | p95 | gate |
|---|---|---|---|
| roundel/tokens − picocolors | +0.2 ms | +2.3 ms | ≤ +10.0 ms |
| roundel/chalk − picocolors | +2.6 ms | +4.8 ms | ≤ +10.0 ms |
| seniority/lilconfig − lilconfig | −1.8 ms | −0.3 ms | ≤ +2.0 ms |
| seniority/dotenv − dotenv | −16.1 ms | +0.8 ms | ≤ +10.0 ms |
| linegauge − string-width | −26.6 ms | −24.7 ms | ≤ 0.0 ms |
| closeout/exit-hook − exit-hook | −0.6 ms | +0.8 ms | ≤ +2.0 ms |
| closeout/signal-exit − signal-exit | +1.1 ms | +3.7 ms | ≤ +2.0 ms |
B1, the half that needs no model — what an agent can act on
Not B1, and not a stand-in for it: this measures nothing about tokens or turns. It measures whether the CLI's answer is legible to an agent, which needs no model at all. Ten tasks per variant, one spawn each, non-TTY with stdin closed — the only environment an agent gets. The same demo program, built on each engine.
| Variant | hangs/100 | exit code | --json | bytes |
|---|---|---|---|---|
burgee | 0 | 100.0% | 100.0% | 164 |
commander | 0 | 40.0% | 25.0% | 31 |
yargs | 0 | 40.0% | 25.0% | 458 |
Exit code is the one that decides an agent's next move: 2 means rewrite the command,
any other non-zero means the command was fine and the world was not. Both incumbents
answer 1 to a usage error, which tells an agent nothing — so it retries a malformed
command until it gives up.
Bytes is reported against us and is not gated. commander reads fewer than we do, because
our errors carry a hint naming the fix. That is a trade — bytes per failure against failed
turns — and only B1 proper can settle it. It is on this page precisely so the trade is
visible rather than quietly omitted.
N10 — the floor, graded by someone else's checklist
Every other number on this page comes from an instrument this repository wrote, and an
instrument its authors wrote can only find the faults they thought of. This one hands the
same demo program to two published, third-party checkers and records what they say:
clispec 0.3.0, the scorer for The CLI Spec v0.3 (six principles, 24
points), and cli-agent-lint 0.3.5 (34 checks,
graded A–F). Both are pinned by version and archive digest in benchmarks/floor-tools.ts,
run offline, and are never re-scored here — a check they fail is listed as failed, even where
we would argue with it.
Measured at commit 28843a5 on 2026-10-19.
| Variant | clispec | cli-agent-lint |
|---|---|---|
burgee | 24 / 24 (Excellent) | 100.0% (A) |
commander | 2 / 24 (Needs Work) | 71.2% (B) |
yargs | 2 / 24 (Needs Work) | 70.9% (B) |
What clispec 0.3.0 failed on burgee's demo:
- none
What cli-agent-lint 0.3.5 did not pass on burgee's demo (warn and info included; skip is not):
- none
B5 — runtime against the incumbent
"Faster" is a claim like any other, so it is measured like one. One realistic workload per pair — the mixed text a CLI prints, a redrawn frame, a 20-row wrapped table, a prompt typed into and submitted — each in its own process, in front of a TTY with colour and hyperlinks forced, and each first proving that ours and the incumbent print the same bytes: a ratio between two different jobs is the flattering number this page exists to refuse. Eleven interleaved rounds; the number is the median of the per-round ratio, ours ÷ theirs, so a round's load lands on both. A reading over its ceiling is confirmed by two more fresh processes before it fails, so load on one process cannot fail a pull request and a regression in every process still does.
The target is ≤ 1.0 for every pair. Where a pair is above it, the gate is a ceiling just above
its CI measurement that may only go down: the PR that makes the pair faster lowers it, and
raising one takes a recorded decision (.sdlc/bands/runtime-ratchets.json).
Measured at commit 440f18f:
| Pair | ours ÷ theirs, p50 | p95 | ≤ 1.0 | gate |
|---|---|---|---|---|
| paratext ÷ ansi-escapes | 1.085× | 1.114× | ❌ not met | ≤ 1.15 |
| paratext/terminal-link ÷ terminal-link | 0.507× | 0.791× | ✅ met | ≤ 0.95 |
| linegauge ÷ string-width | 0.739× | 0.884× | ✅ met | ≤ 0.85 |
| linegauge/strip ÷ strip-ansi | 1.036× | 1.049× | ❌ not met | ≤ 1.1 |
| linegauge/wrap ÷ wrap-ansi | 0.732× | 0.784× | ✅ met | ≤ 0.85 |
| linegauge/slice ÷ slice-ansi | 0.957× | 1.134× | ✅ met | ≤ 1.05 |
| roundel/chalk ÷ chalk | 1.240× | 1.282× | ❌ not met | ≤ 1.35 |
| bellpull/node-which ÷ which | 0.314× | 0.319× | ✅ met | ≤ 0.5 |
| bellpull ÷ tinyexec | 0.986× | 1.008× | ✅ met | ≤ 1 |
| flagstaff/ora ÷ ora | 0.949× | 1.037× | ✅ met | ≤ 1.05 |
| flagstaff/log-update ÷ log-update | 0.762× | 1.435× | ✅ met | ≤ 1.05 |
| flagstaff/boxen ÷ boxen | 0.370× | 0.393× | ✅ met | ≤ 0.45 |
| flagstaff/cli-table3 ÷ cli-table3 | 0.390× | 0.467× | ✅ met | ≤ 0.45 |
| caique/clack ÷ @clack/prompts | 1.102× | 1.167× | ❌ not met | ≤ 1.7 |
| burgee/commander ÷ commander | 1.044× | 1.245× | ❌ not met | ≤ 1.2 |
| burgee/yargs ÷ yargs | 1.081× | 1.123× | ❌ not met | ≤ 1.1 |
The ceilings every pull request is gated on today:
| Entry point | Replaces | Target | Ceiling | First ceiling | Steps |
|---|---|---|---|---|---|
paratext | ansi-escapes | ≤ 1 | ≤ 1.15 | 12.35 (2026-09-29) | 3 |
paratext/terminal-link | terminal-link | ≤ 1 | ≤ 0.95 | 29.7 (2026-09-29) | 3 |
linegauge | string-width | ≤ 1 | ≤ 0.85 | 1.95 (2026-09-29) | 4 |
linegauge/strip | strip-ansi | ≤ 1 | ≤ 1.1 | 5.6 (2026-09-29) | 4 |
linegauge/wrap | wrap-ansi | ≤ 1 | ≤ 0.85 | 2.6 (2026-09-29) | 4 |
linegauge/slice | slice-ansi | ≤ 1 | ≤ 1.05 | 11.65 (2026-09-29) | 4 |
roundel/chalk | chalk | ≤ 1 | ≤ 1.35 | 5.5 (2026-09-29) | 4 |
bellpull/node-which | which | ≤ 1 | ≤ 0.5 | 1.8 (2026-09-29) | 3 |
bellpull | tinyexec | ≤ 1 | ≤ 1 | 1 (2026-09-30) | 1 |
flagstaff/ora | ora | ≤ 1 | ≤ 1.05 | 1.8 (2026-09-29) | 5 |
flagstaff/log-update | log-update | ≤ 1 | ≤ 1.05 | 4.2 (2026-09-29) | 4 |
flagstaff/boxen | boxen | ≤ 1 | ≤ 0.45 | 1.3 (2026-09-29) | 5 |
flagstaff/cli-table3 | cli-table3 | ≤ 1 | ≤ 0.45 | 2.2 (2026-09-29) | 4 |
caique/clack | @clack/prompts | ≤ 1 | ≤ 1.7 | 3.35 (2026-09-29) | 4 |
burgee/commander | commander | ≤ 1 | ≤ 1.2 | 1.6 (2026-09-29) | 3 |
burgee/yargs | yargs | ≤ 1 | ≤ 1.1 | 1.55 (2026-09-29) | 3 |
B3 — compatibility
Read from compat-oracle and never recomputed here: two implementations of a
compatibility rate produce two rates. The full method, and the control column that proves
the gate works, are on Compatibility.
| Host | Passing | Rate |
|---|---|---|
| ansi-escapes | 4 | 100.0% |
| boxen | 213 | 100.0% |
| chalk | 59 | 100.0% |
| clack | 16 | 100.0% |
| cli-cursor | 8 | 100.0% |
| cli-table3 | 29 | 100.0% |
| cli-truncate | 12 | 100.0% |
| colorette | 67 | 100.0% |
| commander | 1,360 | 100.0% |
| cosmiconfig | 242 | 99.6% |
| cross-spawn | 68 | 100.0% |
| dotenv | 197 | 100.0% |
| execa | 0 | 0.0% |
| exit-hook | 21 | 100.0% |
| extra-typings | 369 | 100.0% |
| find-up | 104 | 100.0% |
| ink | 1,304 | 100.0% |
| inkjs-ui | 102 | 100.0% |
| inquirer-core | 45 | 100.0% |
| inquirer-prompts | 221 | 100.0% |
| kleur | 15 | 100.0% |
| lilconfig | 77 | 100.0% |
| log-update | 99 | 100.0% |
| meow | 146 | 98.6% |
| onetime | 6 | 100.0% |
| ora | 99 | 100.0% |
| picocolors | 1 | 100.0% |
| rc | 1 | 100.0% |
| restore-cursor | 6 | 100.0% |
| signal-exit | 134 | 99.3% |
| slice-ansi | 104 | 100.0% |
| string-width | 233 | 100.0% |
| strip-ansi | 8 | 100.0% |
| supports-color | 55 | 100.0% |
| term-img | 18 | 100.0% |
| terminal-link | 8 | 100.0% |
| which | 5 | 100.0% |
| widest-line | 1 | 100.0% |
| wrap-ansi | 85 | 100.0% |
| yargs | 816 | 100.0% |
| yoctocolors | 78 | 100.0% |
B4 — weight
Bundled is what your application grows by when you import that entry point: a fixture importing exactly it, one symbol used, esbuild-minified — the incumbent measured by the same command over the same fixture shape. A tarball size answers a different question.
Installed is what npm install puts on disk, including everything the package drags
in. Ours drag nothing, which is where the two columns diverge most; but one of our packages
serves every entry point it publishes, so the installed column is not per-entry-point and
nothing gates on it.
| Entry point | Replaces | Bundled | Theirs | Ratio | Installed | Theirs |
|---|---|---|---|---|---|---|
burgee | cac | 24,460 | 10,452 | 2.340× | 1,722,512 | 41,198 |
burgee/commander | commander | 55,393 | 39,084 | 1.417× | 1,722,512 | 207,368 |
burgee/yargs | yargs | 108,897 | 111,686 | 0.975× | 1,722,512 | 528,744 |
roundel/chalk | chalk | 4,790 | 8,002 | 0.599× | 131,561 | 56,180 |
roundel/tokens | picocolors | 383 | 2,557 | 0.150× | 131,561 | 6,373 |
roundel/colorette | colorette | 1,794 | 1,973 | 0.909× | 131,561 | 17,009 |
roundel/kleur | kleur | 1,036 | 1,847 | 0.561× | 131,561 | 20,250 |
roundel/kleur/colors | kleur/colors | 621 | 688 | 0.903× | 131,561 | 20,250 |
roundel/supports-color | supports-color | 1,764 | 2,128 | 0.829× | 131,561 | 11,618 |
roundel/yoctocolors | yoctocolors | 2,247 | 2,363 | 0.951× | 131,561 | 13,519 |
flagstaff/ora | ora | 55,760 | 59,460 | 0.938× | 690,089 | 285,079 |
flagstaff/boxen | boxen | 28,671 | 41,105 | 0.698× | 690,089 | 804,192 |
flagstaff/cli-table3 | cli-table3 | 24,403 | 34,620 | 0.705× | 690,089 | 153,737 |
flagstaff/spinner | ora | 7,207 | 59,460 | 0.121× | 690,089 | 285,079 |
flagstaff/box | boxen | 20,696 | 41,105 | 0.503× | 690,089 | 804,192 |
flagstaff/table | cli-table3 | 19,184 | 34,620 | 0.554× | 690,089 | 153,737 |
flagstaff/log-update | log-update | 18,751 | 36,300 | 0.517× | 690,089 | 262,051 |
linegauge | string-width | 5,646 | 6,013 | 0.939× | 107,198 | 37,194 |
linegauge/wrap | wrap-ansi | 11,427 | 14,372 | 0.795× | 107,198 | 80,578 |
linegauge/slice | slice-ansi | 11,411 | 14,634 | 0.780× | 107,198 | 66,999 |
linegauge/strip | strip-ansi | 272 | 457 | 0.595× | 107,198 | 10,484 |
paratext | ansi-escapes | 7,102 | 4,351 | 1.632× | 104,109 | 30,912 |
bellpull | tinyexec | 5,883 | 5,969 | 0.986× | 97,766 | 26,969 |
seniority/lilconfig | lilconfig | 3,286 | 5,365 | 0.612× | 225,522 | 17,985 |
seniority/dotenv | dotenv | 5,966 | 11,564 | 0.516× | 225,522 | 46,091 |
seniority/cosmiconfig + seniority/find-up | cosmiconfig + find-up | 12,877 | 83,870 | 0.154× | 225,522 | 1,892,988 |
closeout/exit-hook | exit-hook | 1,579 | 1,645 | 0.960× | 110,552 | 13,200 |
closeout/signal-exit | signal-exit | 2,657 | 2,856 | 0.930× | 110,552 | 76,966 |
controlroom/ink + react + react-reconciler | ink + react | 531,706 | 673,137 | 0.790× | 3,529,608 | 8,165,450 |
controlroom | ink | 41,982 | 642,330 | 0.065× | 1,417,485 | 7,986,787 |
examples/dashboard/dashboard.mjs | examples/dashboard-ink/screen.mjs | 48,366 | 730,210 | 0.066× | 1,417,485 | 8,470,778 |
A complete CLI — the dependency bill
What npm install puts on disk for a CLI that parses its arguments, colours its output, shows a
spinner, prints a table and asks a question. Ours is the union of each package installed alone,
offline, from its tarball (supply chain). Theirs is each incumbent's tree as
package-lock.json resolves it, and each tree's size agrees with the one the upstream watch
resolved from the registry for the same release. A package installed at two versions counts twice:
both are on disk.
Paired by job: parse arguments (burgee for commander), colour (roundel for chalk), spinner (flagstaff for ora), table (flagstaff for cli-table3), prompts (caique for @inquirer/prompts).
npm install | Packages installed | Beyond the ones named | Installed at two versions | From outside the family |
|---|---|---|---|---|
burgee + roundel + flagstaff + caique | 9 | 5 | 0 | 0 |
commander + chalk + ora + cli-table3 + @inquirer/prompts | 49 | 44 | 3 | — |
Ours installs bellpull, burgee, caique, closeout, flagstaff, linegauge, paratext, roundel, seniority, every one published from this repository. Theirs installs ansi-regex, string-width, strip-ansi twice, at two versions each; the incumbents are separate projects, so the last column has no meaning for them.
Reproduce
npm install
npx turbo run build
npm run bench -- --checkResults are written to benchmarks/results/<suite>/<date>.json and read by the Stage 6
control bands in .sdlc/bands/control-bands.json. The suite refuses to emit a band value
it did not measure; see benchmarks/README.md.