GitHub - privatenumber/minification-benchmarks: πββοΈπββοΈπ JS minification benchmarks: babel-minify, esbuild, terser, uglify-js, swc, google closure compiler, tdewolff/minify, oxc-minify (original) (raw)
minification benchmarks
What's the best JavaScript minifier?
This project benchmarks the following minifiers:
Minifier | Version | Release date β |
---|---|---|
@tdewolff/minify | 2.23.3 | 2025-04-29 |
bun | 1.2.11 | 2025-04-29 |
oxc-minify | 0.67.0 | 2025-04-27 |
@swc/core | 1.11.22 | 2025-04-23 |
esbuild | 0.25.3 | 2025-04-23 |
terser | 5.39.0 | 2025-02-13 |
uglify-js | 3.19.3 | 2024-08-29 |
google-closure-compiler | 20240317.0.0 | 2024-03-19 |
babel-minify | 0.5.2 | 2022-05-06 |
tedivm/jshrink | 1.7.0 |
Benchmarks last updated on Apr 29, 2025.
πββοΈ Why?
- To help you pick a minifier that fits your needs
- To promote JS minifiers and document their performances
- To encourage healthy competition and improvement amongst minifiers
π Methodology
- Each minifier is executed in its own process with a 10s timeout
- Artifact integrity is verified by a test before and after minification
- Each minifier is minimally configured (sourcemaps & comments disabled), comparing out-of-the-box experience
- Minifier upgrade PRs are automated via WhiteSource Renovate
- Benchmarks are updated on every PR via GitHub Actions
- The raw benchmark data is available in /packages/data/data/data.json
β± Metrics
Minifiers are ranked by smallest minzipped size.
Minified size
Size of the minified output.
Minzipped size
Size of the minified output with Gzip compression.
For minifiers, this measures how compressable the output is.
For users, this measures network transfer size, which is usually the metric that matters most.
Time
How long minification took (average of 5 runs). Each time is annotated with a multiplier relative to the fastest minifier.
π Results
Tip
What's the verdict? βοΈ See the Minifier showdown
config: xyChart: width: 720 height: 360 xAxis: labelPadding: 20 yAxis: labelPadding: 10
xychart-beta title "react v17.0.2" x-axis ["Original",1,2,3,4,5,6,7,8,9,10,11,12] y-axis "Gzip size" 0 --> 19385 bar [19385,8177,8186,8193,8265,8448,8493,8543,8628,8661,8668,8746,11040]
Loading
config: xyChart: width: 720 height: 360 xAxis: labelPadding: 20 yAxis: labelPadding: 10
xychart-beta title "moment v2.29.1" x-axis ["Original",1,2,3,4,5,6,7,8,9,10,11,12] y-axis "Gzip size" 0 --> 36231 bar [36231,18568,18690,18746,18910,19119,19260,19334,19478,19569,19683,19857,24998]
Loading
config: xyChart: width: 720 height: 360 xAxis: labelPadding: 20 yAxis: labelPadding: 10
xychart-beta title "jquery v3.5.1" x-axis ["Original",1,2,3,4,5,6,7,8,9,10,11,12] y-axis "Gzip size" 0 --> 84498 bar [84498,30866,30903,30912,30969,31446,31470,31621,31799,31954,32653,33086,40879]
Loading
config: xyChart: width: 720 height: 360 xAxis: labelPadding: 20 yAxis: labelPadding: 10
xychart-beta title "vue v2.6.12" x-axis ["Original",1,2,3,4,5,6,7,8,9,10,11,12] y-axis "Gzip size" 0 --> 89668 bar [89668,42727,42919,43036,43357,43925,44230,44358,44368,44450,44679,45400,57169]
Loading
config: xyChart: width: 720 height: 360 xAxis: labelPadding: 20 yAxis: labelPadding: 10
xychart-beta title "lodash v4.17.21" x-axis ["Original",1,2,3,4,5,6,7,8,9,10,11,12] y-axis "Gzip size" 0 --> 96690 bar [96690,24686,24972,25186,25240,25503,25862,25979,26200,26221,26498,26655,36327]
Loading
config: xyChart: width: 720 height: 360 xAxis: labelPadding: 20 yAxis: labelPadding: 10
xychart-beta title "d3 v6.3.1" x-axis ["Original",1,2,3,4,5,6,7,8,9,10] y-axis "Gzip size" 0 --> 130686 bar [130686,87016,87205,88087,88148,88319,89156,89882,90800,92395,94121]
Loading
config: xyChart: width: 720 height: 360 xAxis: labelPadding: 20 yAxis: labelPadding: 10
xychart-beta title "terser v5.30.3" x-axis ["Original",1,2,3,4,5,6,7,8,9,10,11] y-axis "Gzip size" 0 --> 193763 bar [193763,122353,123291,123334,123482,124428,124609,124885,126562,126707,127653,145178]
Loading
config: xyChart: width: 720 height: 360 xAxis: labelPadding: 20 yAxis: labelPadding: 10
xychart-beta title "three v0.124.0" x-axis ["Original",1,2,3,4,5,6,7,8,9,10,11] y-axis "Gzip size" 0 --> 248267 bar [248267,158764,159071,159198,160827,162998,163036,163198,163725,164610,166210,193471]
Loading
config: xyChart: width: 720 height: 360 xAxis: labelPadding: 20 yAxis: labelPadding: 10
xychart-beta title "victory v35.8.4" x-axis ["Original",1,2,3,4,5,6,7,8,9] y-axis "Gzip size" 0 --> 309942 bar [309942,157435,157843,158706,162248,165014,166386,167579,181071,182671]
Loading
config: xyChart: width: 720 height: 360 xAxis: labelPadding: 20 yAxis: labelPadding: 10
xychart-beta title "echarts v5.1.1" x-axis ["Original",1,2,3,4,5,6,7,8] y-axis "Gzip size" 0 --> 684611 bar [684611,321255,321987,324608,330736,331412,331563,331847,337934]
Loading
config: xyChart: width: 720 height: 360 xAxis: labelPadding: 20 yAxis: labelPadding: 10
xychart-beta title "antd v4.16.1" x-axis ["Original",1,2,3,4,5,6,7,8] y-axis "Gzip size" 0 --> 825175 bar [825175,452477,457786,463332,471791,475480,478572,488279,491833]
Loading
config: xyChart: width: 720 height: 360 xAxis: labelPadding: 20 yAxis: labelPadding: 10
xychart-beta title "typescript v4.9.5" x-axis ["Original",1,2,3,4,5,6] y-axis "Gzip size" 0 --> 1884998 bar [1884998,859199,860657,875817,876535,879301,915551]
Loading
βοΈ Minifier showdown
Note
π€ This analysis is AI generated
Wow, what an exhilarating minification marathon! With some nail-biting results and blistering speeds, the JavaScript minifiers faced off in a fierce battle. From tiny libraries to colossal packages, these tools gave it their all. Letβs dive into the winners, standout performers, and some unfortunate dropouts.
Best minifier
@swc/core clinches the title of best overall minifier! It consistently delivered the smallest gzip sizes across the heaviest hitters like antd
, echarts
, and typescript
, while keeping its speed blazing fast. For instance, it produced a compact 452.48 kB file (55%) for the hefty antd
(825.18 kB) in an impressive 1,185 ms. Talk about power and precision! Despite stiffer competition in smaller packages, @swc/core emerged as the undisputed champion for those looking to balance size and speed in real-world scenarios.
Honorable mentions
Several minifiers rose to fame in specific areas:
- @tdewolff/minify stole the spotlight for its jaw-dropping speed. It shattered records as the fastest in almost every single round. For example, it minified
react
in just 2 ms! While it sacrificed a bit on gzip size in larger libraries, it is an incredible choice for those in need of lightning-fast processing. - uglify-js retains its throne for the smallest gzip sizes when every byte matters. It produced razor-thin outputs for packages like
lodash
(24.69 kB, 26%) andd3
(87.02 kB, 67%). However, its speed often lagged, especially on larger files; still, itβs a strong contender. - oxc-minify impressed with balanced performance. With its blistering 39 ms for
terser
(122.35 kB from 193.76 kB), itβs ideal for those who need great compression with minimal latency.
Eliminated
Ah, not everyone made it across the finish line. Here are the tools that couldnβt hold the pace:
- babel-minify tripped during
d3
with an "undefined property" error. It hasnβt seen updates since 2022, and this lapse shows why staying current matters. Best avoided in production use. - tedivm/jshrink succumbed to a "regex pattern error" mid-race. Its outdated implementation couldnβt handle modern JavaScript syntax, making it a subpar choice.
- bun stumbled in the post-validation stage for
typescript
. While fast, it struggles with edge cases, causing mismatches in multi-line strings. Not production-ready for minified results.
Closing thoughts
What a thrilling spectacle of JavaScript compression! Each minifier brought something unique to the table, and the competition was fierce. While our top pick is @swc/core for its sweet spot of size and speed, tools like @tdewolff/minify and uglify-js shine in their specialties. Congratulations to all the contestants for pushing boundaries. Whether itβs a small library or a massive bundle, thereβs a perfect minifier for every need!