@jsquash/jpeg 1.6.0 (Squoosh mozjpeg WASM) vs sharp 0.35.5 mozjpeg on one 1920×1080 JPEG → q80 encode from pre-decoded RGBA. Warm medians (7 rounds after 1 warm-up): Squoosh WASM 483 ms / 675,247 B vs sharp mozjpeg 291 ms / 546,546 B (~1.7×). Context: sharp decode+encode mozjpeg 303 ms; sharp libvips jpeg from raw 23 ms / 675,714 B. Fixture /workspace/bench-squoosh-sharp/. @squoosh/lib 0.5.3 fails on Node 22.
4 min read
I encoded one 1920×1080 photo at JPEG quality 80 seven times on this box: Squoosh mozjpeg WASM (@jsquash/jpeg 1.6) median 483 ms (675 KB out), sharp 0.35 mozjpeg from the same raw RGBA median 291 ms (547 KB out) — about 1.7× faster and ~19% smaller.
Short answer: for Node pipelines that can load a native binding, sharp won this encode. Squoosh WASM still fits browser or edge runtimes that refuse native addons. No affiliate links in this post.
| Path | Median wall | Min / Max | Output JPEG |
|---|---|---|---|
| Squoosh WASM (@jsquash/jpeg) q80 encode-only | 483 ms | 449 / 510 | 675,247 B |
| sharp 0.35 mozjpeg from raw RGBA q80 | 291 ms | 290 / 313 | 546,546 B |
| sharp mozjpeg decode+encode from JPEG (context) | 303 ms | 297 / 355 | 546,546 B |
| sharp libvips jpeg from raw (context) | 23 ms | 22 / 29 | 675,714 B |
Same 1920×1080 source, same box. Headline numbers are encode-only from identical RGBA. sharp still finished faster than Squoosh WASM and wrote a smaller q80 file. For resize-first pipelines, see Sharp vs Jimp. For gulp-plugin minify, see Sharp vs imagemin. For build minify cousins, see terser vs esbuild/swc minify.
Yes, when you cannot ship a native sharp binary: browser tabs, some edge runtimes, or locked-down CI images. @jsquash/jpeg still needs a WASM init step on Node 22. On this Linux box with a normal sharp install, sharp mozjpeg was the default.
Treat this post as Squoosh mozjpeg WASM vs sharp mozjpeg on one JPEG q80 encode, not a full codec survey. libvips jpeg (mozjpeg false) was far faster (~23 ms) at a larger file — that trade-off belongs in a separate call.
| Situation | My pick |
|---|---|
| Node CI or server that can install sharp | sharp |
| Browser or no-native-addon runtime | Squoosh / <br/>jsquash |
| Need smaller q80 JPEGs in Node | sharp mozjpeg |
| Need resize + encode in one step | sharp |
| Watching asset budgets after images | Pair with size-limit vs bundlesize and Vite vs Parcel |
| Already on Astro/Vite using sharp | Stay; do not add Squoosh beside it |
Bottom line: on one 1920 photo at q80, Squoosh WASM returned in 483 ms median with a 675 KB file while sharp mozjpeg from the same raw needed 291 ms and 547 KB. Who should not switch: teams stuck without native addons who already ship in the browser.
How this was made: I reused a 1920×1080 JPEG on the ShopperCove box, preloaded Squoosh mozjpeg WASM via @jsquash/jpeg, timed interleaved encode rounds against sharp after a warm-up, recorded JSON medians and output bytes; the write-up was drafted with AI help and checked against that output.
Lab evidence
Hands-on on ShopperCove box 6 Oct 2026 ~00:26–00:28 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 22.20.0). @jsquash/jpeg 1.6.0 (Squoosh mozjpeg WASM; @squoosh/lib 0.5.3 fails on Node 22) vs sharp 0.35.5. Fixture /workspace/bench-squoosh-sharp/: src-1920.jpg 1920×1080 JPEG ~981 KB; encode JPEG q80 from pre-decoded RGBA. 1 warm-up + 7 interleaved rounds. Medians Squoosh WASM 483 ms (449–510) / 675,247 B vs sharp mozjpeg from raw 291 ms (290–313) / 546,546 B (~1.7×). Context sharp decode+encode mozjpeg 303 ms; sharp libvips jpeg from raw 23 ms / 675,714 B. Raw: /workspace/bench-squoosh-sharp/res-squoosh-sharp.json. Not tested: browser Squoosh UI, WebP/AVIF, workers, Cloudflare Workers, Windows/macOS, serverless cold starts. No affiliate.
mozjpeg cjpeg 3.3.1 (mozjpeg npm 8.0.0) vs libvips jpeg via sharp 0.35.5 (mozjpeg:false) on one 1920×1080 JPEG → q80. Warm medians (7 rounds after 1 warm-up): cjpeg 385 ms / 675,128 B vs libvips jpeg 31 ms / 675,714 B (~12×). Context: sharp mozjpeg:true 308 ms / 546,546 B. Fixture /workspace/bench-mozjpeg-libvips/. cjpeg timed with spawn + PPM read.
Hands-on6 Oct 20264 min read
sharp 0.35.5 vs imagemin 9.0.1 + imagemin-mozjpeg 10.0.0 on one 1920×1080 JPEG → JPEG q80 (no resize). Warm medians (7 rounds after 1 warm-up): sharp 305 ms / 546,546 B vs imagemin-mozjpeg 399 ms / 675,128 B (~1.3×). Context: sharp resize 800 q80 median 115 ms / 142,435 B. Fixture /workspace/bench-sharp-imagemin/.
Hands-on6 Oct 20264 min read
sharp 0.35.5 vs Jimp 1.6.1 on one 1920×1080 JPEG → width 800 JPEG q80. Warm medians (7 rounds after 1 warm-up): sharp 112 ms / 142,435 B vs Jimp 366 ms / 269,590 B (~3.3×). Fixture /workspace/bench-sharp-jimp/.
Hands-on6 Oct 20264 min read