Five rounds give a median and show the spread.
cd ~/v5-ch1 && RUNS=5 ./bench.shOutput
run 1 npm cold 6.54s warm 0.95s run 1 pnpm cold 2.52s warm 0.26s run 1 bun cold 1.73s warm 0.08s run 1 yarn-pnp cold 4.43s warm 0.52s run 1 yarn-nm cold 5.17s warm 0.92s ...
| Tool | Cold median | Cold range | Warm median | Warm range |
|---|---|---|---|---|
| npm 11.19.0 2,036 | 6.12 s | 5.94-6.54 s | 0.94 s | 0.89-1.80 s |
| pnpm 12.6.0 69,400 | 2.58 s | 2.52-3.02 s | 0.22 s | 0.22-0.26 s |
| Bun 1.4.2 73,307 | 1.88 s | 1.73-2.16 s | 0.08 s | 0.07-0.13 s |
| Yarn 4.18.1 11,798 , PnP | 5.31 s | 3.88-6.56 s | 0.57 s | 0.50-1.35 s |
| Yarn 4.18.1, node-modules | 5.21 s | 4.97-6.07 s | 0.82 s | 0.82-0.92 s |

Cold, Bun was about 3.3 times faster than npm and pnpm about 2.4 times; both Yarn modes landed near npm, and PnP's wide spread (3.9 to 6.6 s) shows network latency dominating. Warm, Bun took 0.08 s, about 12 times faster than npm, and pnpm 0.22 s: both link files from a cache instead of extracting archives. npm's single 1.80 s warm run is the kind of outlier a busy neighbor on a shared machine causes, which is why medians matter.