Plate 74
Should You Leave Terser? 824ms vs 41ms
Terser 5.51.2 vs esbuild 0.28.2 vs SWC 1.16.13 minify on a 403,418-byte unminified ESM bundle (800 modules): medians 824 ms / 41 ms / 70 ms. Output sizes 219492 / 207619 / 199712 B. Leave Terser if you only need fast minify; keep it for Terser-only compress options.
Aditya Challa5 min read
On a 403 KB unminified JavaScript bundle (800 generated ESM modules, esbuild-bundled without minify), Terser 5.51.2 took a median 824 ms. esbuild 0.28.2 took 41 ms. SWC 1.16.13 took 70 ms. Same machine, same input, library minify APIs for each tool.
Short answer: leave Terser for esbuild or SWC if you only need a fast production minify step and you are not depending on Terser-only compress options. Keep Terser when you need a specific compress pass that the others do not match. 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:00 to 23:10 IST). Shared box; tools interleaved each round.
- Fixture: 800 generated ESM modules bundled with esbuild into one file with minify off (
fixture.unmin.js, 403,418 bytes). No React, no CSS, no TypeScript in the minify step. - Tools:
terser5.51.2 (compress+mangle, comments off),esbuild0.28.2 (transformwithminify: true,legalComments: 'none', target ES2020),@swc/core1.16.13 (minifywith compress + mangle,module: true). - Timing: five interleaved warm runs after one warmup each. Median wall-clock of the minify call only (not cold process start).
- Output sizes: esbuild 207,619 B; SWC 199,712 B; Terser 219,492 B. SWC was smallest here; Terser was largest and slowest.
- One surprise: SWC beat Terser on size (about 199 KB vs 219 KB) while still finishing in 70 ms. esbuild won speed (41 ms) with a mid-size output.
- Not tested: minify quality on real app code, source maps, Terser
passes/pure_funcs/drop_console, Safari quirks, gzip/brotli of each output, Windows/macOS, bundler-integrated minify (Webpack TerserPlugin vs esbuild minify plugin), cold CLI startup.
Is esbuild faster than Terser and SWC?
| Tool | Median | Runs (ms) | Output bytes |
|---|---|---|---|
| esbuild 0.28.2 | 41 ms | 38 / 47 / 40 / 46 / 41 | 207,619 |
| SWC 1.16.13 | 70 ms | 70 / 71 / 80 / 63 / 60 | 199,712 |
| Terser 5.51.2 | 824 ms | 994 / 876 / 721 / 763 / 824 | 219,492 |
On this fixture esbuild was about 20x faster than Terser and about 1.7x faster than SWC. SWC was about 12x faster than Terser and produced the smallest file. Terser was both the slowest and the largest output here, so the leave-Terser case is strong when your CI still spends nearly a second on minify alone.
If your production path already minifies through Vite or esbuild, do not add a second Terser pass hoping for a smaller file until you measure. The SWC vs esbuild vs Babel transform post is the related transform decision on this site; the Rspack vs Webpack build post is the bundler path that often swaps Terser for a native minify.
What do you lose leaving Terser?
Terser's compress options are deep. Teams that rely on multi-pass compression, custom pure_funcs, or rare syntax edge cases may see different runtime behavior after a switch. This fixture was synthetic ESM with plain loops and object literals. Real apps with class fields, optional chaining patterns, or library code marked with pure comments can change the gap.
Also match minify to the bundler you keep. Vite and esbuild pipelines already minify with esbuild by default. Rspack and SWC-first stacks lean on SWC minify. Swapping only the minify library while leaving an old TerserPlugin config in Webpack is fine as an experiment, but CI should time the full production build. The Webpack 5.111 ESM notes are the Webpack baseline on this site.
Should you leave Terser for esbuild or SWC?
| Situation | My pick |
|---|---|
| Webpack still runs TerserPlugin and CI minify is hundreds of ms | Prefer esbuild minify plugin or SWC minify; re-time CI |
| Already on Vite / esbuild for build and minify | Stay; do not add Terser for a micro size chase |
| Moving Webpack to Rspack | Take the bundler's native minify; see the Rspack migrate path |
| You need a Terser-only compress option that fails elsewhere | Keep Terser for that entry; split the pipeline if needed |
| You only care about final transfer size | Compare gzip or brotli of each output, not raw bytes alone |
Bottom line: on a 403 KB JS bundle, Terser took 824 ms, esbuild took 41 ms, and SWC took 70 ms. Who should not switch yet: teams blocked on a Terser-only compress setting. Everyone else still paying nearly a second for minify should measure their own bundle the same way before rewriting the plugin list.
How this was made: I generated the modules, bundled them without minify, ran every minify API on the ShopperCove test box, and kept the timing JSON; the write-up was drafted with AI help and checked against that output.
Sources
- https://terser.org/docs/api-reference/
- https://esbuild.github.io/api/#minify
- https://swc.rs/docs/configuration/minification
- https://www.npmjs.com/package/terser
- https://www.npmjs.com/package/esbuild
- https://www.npmjs.com/package/@swc/core
Related
- https://www.shoppercove.com/blog/swc-vs-esbuild-babel
- https://www.shoppercove.com/blog/rspack-vs-webpack
- https://www.shoppercove.com/blog/rspack-2-2-8-resolver-cache-memory-october-2026
- https://www.shoppercove.com/blog/webpack-5-111-esm-output-stable-september-2026
- https://www.shoppercove.com/blog/vite-8-3-2-renderbuilturl-bundled-dev-sourcemaps-october-2026
- https://www.shoppercove.com/blog/vite-plus-1-0-unified-toolchain-october-2026
- https://www.shoppercove.com/blog/biome-vs-eslint-prettier
- https://www.shoppercove.com/blog/tsx-vs-ts-node
Lab evidence
What I found running this
Hands-on on ShopperCove box 5 Oct 2026 ~23:00-23:10 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 20.19.2). Fixture: 800 generated ESM modules bundled with esbuild (minify off) into fixture.unmin.js (403418 bytes). Versions: terser 5.51.2 (compress+mangle, comments false); esbuild 0.28.2 (transform minify true, legalComments none, target es2020); @swc/core 1.16.13 (minify compress+mangle, module true). Wall medians (5 interleaved after warmup): esbuild 40.878 ms (37.820/46.723/39.653/45.905/40.878); SWC 69.778 ms (69.778/71.010/79.501/63.139/60.027); Terser 824.270 ms (993.935/876.233/721.450/762.849/824.270). Output bytes: esbuild 207619; SWC 199712; Terser 219492. Raw: /workspace/bench-minify/res-minify.json. Not tested: minify quality on real apps, source maps, Terser multi-pass/pure_funcs, gzip/brotli, Windows/macOS, bundler-plugin paths, cold CLI start. No affiliate.
Related links
Plate 45
Should You Leave Depcruise? 679ms Test
Madge 8.0.0 vs dependency-cruiser 16.10.2 on 116 JS files: median wall 679 ms vs 1122 ms (~1.65x). Both found the same 2 circular dependency groups. Depcruise also reported 120 modules / 193 dependencies.
5 Oct 2026
Plate 31
Should You Leave Rollup? 964ms vs 246ms
Rolldown 1.2.12 vs Rollup 4.64.0 on 501 ESM files (197380 B source): median wall 245.617 ms vs 964.3 ms (~3.9x). Output 130522 vs 126894 B. Direct node bin, 5 interleaved warm runs, no minify.
5 Oct 2026
Plate 10
Rspack 2.2.8: resolver cache, memory shrinks, modern-module deferral (28 Sep 2026)
Rspack published @rspack/core@2.2.8 on 28 September 2026: resolver caching, memory shrinks, and modern-module deferral fixes on the 2.2 line. Upgrade checklist only; no affiliate.
5 Oct 2026