ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 80

  1. Blog

size-limit vs bundlesize: Should You Switch? 761ms vs 604ms

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.

Aditya Challa·5 October 2026·5 min read

Hands-on
On this page
  1. What I tested
  2. Is size-limit slower than bundlesize?
  3. Do the reported sizes match?
  4. Should you switch from bundlesize to size-limit?
  5. Sources
  6. Related

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.

What I tested

  • Machine: 8 vCPU Intel Xeon / 15 GB RAM Linux cloud box, Node 20.19.2, tested 5 Oct 2026 (about 23:29 to 23:31 IST). Shared box; CLI runs interleaved after one warmup each.
  • Fixture: /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.
  • Tools: 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.
  • Timing: seven interleaved 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.
  • Findings: size-limit default (brotli) median 761.3 ms (runs 705 / 710 / 731 / 761 / 792 / 792 / 839). bundlesize gzip median 603.5 ms (587 / 590 / 603 / 604 / 604 / 604 / 618). size-limit gzip mode median 620.8 ms.
  • Reported sizes for app: size-limit brotli 57.69 kB, size-limit gzip 62.20 kB, bundlesize gzip 60.74 kB. Same file, three different compressed numbers.
  • One surprise: most of the 761 vs 604 gap was brotli work, not tool overhead. Gzip-mode size-limit landed within ~17 ms of bundlesize.
  • Not tested: @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.

Is size-limit slower than bundlesize?

VariantMedian wallRuns (ms)Compression
size-limit 11.2 file (default)761 ms705 / 710 / 731 / 761 / 792 / 792 / 839brotli
size-limit 11.2 file (gzip: true)621 ms562 / 595 / 621 / 634 / 638gzip
bundlesize 1.0.0-beta.2604 ms587 / 590 / 603 / 604 / 604 / 604 / 618gzip

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.

Do the reported sizes match?

FileRaw bytessize-limit brotlisize-limit gzipbundlesize gzip
dist/app.js132,58057.69 kB62.20 kB60.74 kB
dist/vendor.js87,38034.13 kB37.37 kB36.49 kB
dist/chunk-home.js33,78012.48 kB13.70 kB13.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.

Should you switch from bundlesize to size-limit?

SituationMy pick
CI only checks prebuilt dist/*.js gzip budgetsEither works; bundlesize was ~17 ms faster here in gzip mode
You want brotli budgets that match what CDNs servesize-limit default
You plan to add webpack/esbuild entry measurement latersize-limit (file preset now, webpack/esbuild plugin later)
Stuck on classic bundlesize 0.18.x and install breaks on modern NodeMove to size-limit, or to bundlesize beta / bundlesize2
Need GitHub check runs without writing your own actionCheck 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.

Sources

  • https://github.com/ai/size-limit
  • https://www.npmjs.com/package/size-limit
  • https://www.npmjs.com/package/@size-limit/file
  • https://github.com/siddharthkp/bundlesize
  • https://www.npmjs.com/package/bundlesize
  • https://github.com/siddharthkp/bundlesize2

Related

  • https://www.shoppercove.com/blog/terser-vs-esbuild-swc-minify
  • https://www.shoppercove.com/blog/rolldown-vs-rollup
  • https://www.shoppercove.com/blog/rspack-vs-webpack
  • https://www.shoppercove.com/blog/webpack-5-111-esm-output-stable-september-2026
  • https://www.shoppercove.com/blog/swc-vs-esbuild-babel
  • https://www.shoppercove.com/blog/knip-vs-depcheck
  • https://www.shoppercove.com/blog/vite-8-3-2-renderbuilturl-bundled-dev-sourcemaps-october-2026
  • https://www.shoppercove.com/blog/lightningcss-vs-postcss
size-limitbundlesizebundle sizeperformancecigzipbrotliweb performance

Lab evidence

What I found running this

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.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 48

    Zod vs Valibot: 1.14M vs 0.97M Parses

    zod 4.6.5 vs valibot 1.5.0 on one nested user schema (uuid/email/age/tags/profile/enum). Warm medians after 2k warmup + 9×50k: zod.parse 1,144,494 ops/s vs valibot.parse 968,187 (~1.18×). safeParse fail: valibot 697,760 vs zod 415,523 (~1.7×). esbuild minify+gzip9: 452,999/92,636 B vs 85,126/15,422 B. Package trees ~6.1 MB vs ~1.9 MB. Fixture /workspace/bench-zod-valibot/.

    5 Oct 2026

  • Plate 44

    Playwright vs Cypress: 1.47s vs 4.24s Smoke

    Playwright 1.55.1 Chromium vs Cypress 14.5.4 Electron on one local smoke (visit /, assert h1, click, assert). Warm medians (7 rounds after 1 warm-up): Playwright 1,466 ms vs Cypress 4,243 ms (~2.9x). Disk: PW node_modules ~12 MB + cache ~918 MB; Cypress node_modules ~23 MB + cache ~601 MB. Fixture /workspace/bench-pw-cy/.

    5 Oct 2026

  • Plate 74

    vite-plugin-checker: Plain Vite Shipped My TS Error

    vite-plugin-checker 0.10.3 with enableBuild on Vite 7.3.6 / TS 5.9.3 / React 19: clean wall medians plain 1,949 ms vs checker 2,018 ms (+69 ms) vs tsc --noEmit 985 ms. Injected TS error: plain vite exit 0 (ships dist) x3; checker exit 2 x3; tsc exit 2 x3. Fixture 122 modules.

    5 Oct 2026

On this page

  1. What I tested
  2. Is size-limit slower than bundlesize?
  3. Do the reported sizes match?
  4. Should you switch from bundlesize to size-limit?
  5. Sources
  6. Related
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove