size-limit 11.2.0 (@size-limit/file) vs bundlesize 1.0.0-beta.2 on 3 prebuilt dist JS files: brotli median 761 ms vs gzip 604 ms; size-limit gzip mode 621 ms. App reported 57.69 kB brotli / 62.20 kB gzip / 60.74 kB bundlesize gzip.
5 min read
On three prebuilt dist files (app 133 KB, vendor 87 KB, chunk 34 KB raw), size-limit 11.2.0 with @size-limit/file took a median 761 ms under its default brotli check, and bundlesize 1.0.0-beta.2 took 604 ms under gzip (~1.26x). When I forced size-limit to gzip, the median dropped to 621 ms, within noise of bundlesize.
Short answer: switch to size-limit if you want brotli budgets, webpack/esbuild plugins, or execution-time limits later. Stay on bundlesize if you only gate already-built gzip sizes and your CI already passes. Classic bundlesize 0.18.2 failed to install here (iltorb native build); the beta CLI is what actually ran. No affiliate links in this post.
/workspace/bench-size-limit-bundlesize/dist/ with three entropy-filled ESM bundles — app.js 132,580 B, vendor.js 87,380 B, chunk-home.js 33,780 B. Same files for both tools. Limits set to 70 / 45 / 20 kB so both checks passed.size-limit 11.2.0 + @size-limit/file 11.2.0 (size-limit 14.x requires Node 22+ and crashed on this box with a node:fs/promises glob import). bundlesize 1.0.0-beta.2. Attempted bundlesize@0.18.2; install failed on iltorb / node-gyp.npx size-limit and npx bundlesize wall clocks via process.hrtime around the full command. Separate five-run pass with "gzip": true on each size-limit entry.@size-limit/webpack or @size-limit/esbuild bundling presets, @size-limit/time execution budgets, GitHub status checks, Windows/macOS, CI containers without local npx cache.| Variant | Median wall | Runs (ms) | Compression |
|---|---|---|---|
| size-limit 11.2 file (default) | 761 ms | 705 / 710 / 731 / 761 / 792 / 792 / 839 | brotli |
size-limit 11.2 file (gzip: true) | 621 ms | 562 / 595 / 621 / 634 / 638 | gzip |
| bundlesize 1.0.0-beta.2 | 604 ms | 587 / 590 / 603 / 604 / 604 / 604 / 618 | gzip |
On this fixture, yes for the defaults, no once compression matches. Both tools only read files that already exist under dist/; neither rebuilt the bundles. If your pipeline already emits gzip-equivalent artifacts and you only need a pass/fail byte gate, bundlesize is enough. If you want the same CLI to grow into webpack/esbuild entry budgets later, size-limit is the better home.
For minify and bundler choices that feed these files, see the terser vs esbuild/swc minify post and the rolldown vs rollup post.
| File | Raw bytes | size-limit brotli | size-limit gzip | bundlesize gzip |
|---|---|---|---|---|
| dist/app.js | 132,580 | 57.69 kB | 62.20 kB | 60.74 kB |
| dist/vendor.js | 87,380 | 34.13 kB | 37.37 kB | 36.49 kB |
| dist/chunk-home.js | 33,780 | 12.48 kB | 13.70 kB | 13.38 kB |
No. Brotli beat gzip by about 4 to 5 kB on the app file, which is expected. Even in gzip mode the two CLIs disagreed by about 1.5 kB on app.js because they do not share one compressor implementation. Thresholds tuned on bundlesize numbers will look different under size-limit brotli, and slightly different under size-limit gzip. Re-baseline the day you switch.
Webpack-era apps that still emit a stats JSON may also want a visual analyzer; that is a different job from a CI byte gate. The Rspack vs webpack post and the webpack 5.111 ESM output post cover the bundler side.
| Situation | My pick |
|---|---|
CI only checks prebuilt dist/*.js gzip budgets | Either works; bundlesize was ~17 ms faster here in gzip mode |
| You want brotli budgets that match what CDNs serve | size-limit default |
| You plan to add webpack/esbuild entry measurement later | size-limit (file preset now, webpack/esbuild plugin later) |
| Stuck on classic bundlesize 0.18.x and install breaks on modern Node | Move to size-limit, or to bundlesize beta / bundlesize2 |
| Need GitHub check runs without writing your own action | Check each tool's current GitHub app docs before switching |
Bottom line: on three dist files, default size-limit was 761 ms and bundlesize was 604 ms; the gap mostly vanished when both used gzip. Who should not switch yet: teams whose release gate is wired to today's bundlesize gzip numbers and who cannot re-baseline this sprint. For a related unused-export cleanup gate, see the knip vs depcheck post.
How this was made: I generated the three dist fixtures, installed both CLIs on the ShopperCove test box, timed interleaved runs, and kept the JSON; the write-up was drafted with AI help and checked against that output.
Lab evidence
Hands-on on ShopperCove box 5 Oct 2026 ~23:29-23:31 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 20.19.2). Fixture: dist/app.js 132580 B, vendor.js 87380 B, chunk-home.js 33780 B (entropy-filled ESM). Tools: size-limit 11.2.0 + @size-limit/file 11.2.0; bundlesize 1.0.0-beta.2 (bundlesize@0.18.2 install failed on iltorb/node-gyp; size-limit 14.1.0 crashes on Node 20 via node:fs/promises glob). Limits 70/45/20 kB; both passed. 1 warmup each, then 7 interleaved npx wall clocks (process.hrtime). Medians: size-limit brotli 761.3 ms (705.1/710.2/731.3/761.3/792.2/792.4/838.8); bundlesize gzip 603.5 ms (587.2/589.5/602.8/603.5/603.6/604.2/618.0). size-limit gzip:true median 620.8 ms (562.4/594.9/620.8/634.4/638.4). Reported app size: brotli 57685 B, size-limit gzip 62197 B, bundlesize gzip 60.74KB. Raw: /workspace/bench-size-limit-bundlesize/res-size-limit-bundlesize.json. Not tested: webpack/esbuild/time presets, GitHub checks, Windows/macOS. No affiliate.