Skip to Content
New: codec-png-native and codec-png-wasm bring the blazediff-png codec to Node and WebAssembly, faster than spng and jSquash. Read more β†’
Comparevs jSquash

BlazeDiff vs jSquash

@blazediff/codec-png-wasm decodes PNG ~2.7x faster than @jsquash/png, and at default settings it encodes ~14% faster in total, with smaller files. Both are Rust compiled to WebAssembly. jSquash wins some individual encodes, so read the per-fixture tables for your image sizes.

jSquash is a set of browser image codecs derived from Squoosh: AVIF, JPEG, JPEG XL, OxiPNG, PNG, QOI, WebP and resize. Its PNG codec wraps the image-rs png crate, version 0.17. @blazediff/codec-png-wasm is the blazediff-png codec with wasm SIMD, about 150 KB, and it decodes every PNG format to RGBA8.

At a glance

jSquash (@jsquash/png)BlazeDiff (@blazediff/codec-png-wasm)
LicenseApache-2.0MIT
Engineimage-rs png 0.17, compiled to wasmblazediff-png, compiled to wasm with SIMD
RuntimesBrowsers, Workers, Deno; Node is experimentalBrowsers, Workers, Deno, Node
Decode outputImageData, or 16-bit RGBARGBA8 { data, width, height }
Encode optionsBit depthCompression level, filter, color mode
Other formatsSibling packages for AVIF, JPEG, WebP, JXLPNG only
Native twinNo@blazediff/codec-png-native for Node

Benchmarks

Both run single-threaded in Node with wasm SIMD. The default encode is fdeflate with adaptive filtering in BlazeDiff and the png crate default in jSquash. The charts also show zune-png, which writes stored data.

WebAssembly decode (PNG to RGBA8)

TOTAL TIME, BEST-OF Β· 36 FIXTURES Β· IO EXCLUDED

BlazeDiffOther librariesLower is better

Apple M1 Max Β· darwin/arm64 Β· Node v22.14.0 Β· rustc 1.97.1 (8bab26f4f 2026-07-14) Β· best-of, iterations scaled by image size, single-threaded, Node (V8) running wasm32 with SIMD Β· 2026-10-26 Β· 3017cb8-dirty Β· pnpm benchmark png-wasm

Per-fixture results (36)
FixtureMPxblazediffzune-pngjSquashblazediff vs jSquashzune-png vs jSquash
4k/1a.png17.9185ms223ms398ms2.15x1.78x
4k/1b.png17.9163ms206ms378ms2.31x1.84x
4k/2a.png20.0224ms274ms545ms2.44x1.99x
4k/2b.png20.0232ms269ms547ms2.36x2.03x
4k/3a.png24.0245ms310ms569ms2.32x1.83x
4k/3b.png24.0242ms309ms579ms2.39x1.87x
alpha/1a.png0.00.10ms0.12ms0.36ms3.47x3.13x
alpha/1b.png0.00.11ms0.11ms0.36ms3.32x3.17x
blazediff/1a.png0.40.85ms0.97ms4.32ms5.09x4.45x
blazediff/1b.png0.40.80ms1.00ms4.35ms5.47x4.34x
blazediff/2a.png0.40.74ms0.88ms3.66ms4.92x4.14x
blazediff/2b.png0.40.80ms0.97ms3.71ms4.67x3.84x
blazediff/3a.png1.613.48ms16.19ms36.66ms2.72x2.26x
blazediff/3b.png1.613.52ms16.08ms35.38ms2.62x2.20x
blazediff/4a.png3.84.40ms4.74ms31.96ms7.26x6.74x
blazediff/4b.png3.84.51ms4.78ms31.67ms7.02x6.63x
page/1a.png58.9210ms277ms626ms2.97x2.25x
page/1b.png58.9217ms262ms610ms2.80x2.33x
page/2a.png41.747.61ms53.70ms286ms6.01x5.33x
page/2b.png41.746.96ms51.86ms283ms6.02x5.45x
pixelmatch/1a.png0.10.77ms0.94ms1.82ms2.36x1.94x
pixelmatch/1b.png0.10.61ms0.81ms1.81ms2.98x2.24x
pixelmatch/2a.png0.10.20ms0.23ms0.77ms3.83x3.36x
pixelmatch/2b.png0.10.21ms0.23ms0.78ms3.76x3.31x
pixelmatch/3a.png0.10.58ms0.67ms1.52ms2.60x2.26x
pixelmatch/3b.png0.10.55ms0.67ms1.52ms2.76x2.28x
pixelmatch/4a.png0.21.78ms2.21ms4.31ms2.42x1.95x
pixelmatch/4b.png0.21.99ms2.37ms4.68ms2.35x1.97x
pixelmatch/5a.png0.10.56ms0.59ms1.03ms1.84x1.75x
pixelmatch/5b.png0.10.56ms0.55ms0.75ms1.33x1.36x
pixelmatch/6a.png0.10.68ms0.67ms1.32ms1.93x1.95x
pixelmatch/6b.png0.10.90ms0.99ms1.37ms1.53x1.39x
pixelmatch/7a.png0.30.34ms0.39ms1.90ms5.52x4.88x
pixelmatch/7b.png0.30.34ms0.41ms1.88ms5.48x4.58x
same/1a.png1.73.54ms7.37ms14.08ms3.98x1.91x
same/1b.png1.73.56ms7.43ms14.03ms3.95x1.89x
TOTAL1.87s2.31s5.03s2.69x2.18x

WebAssembly encode, no compression

TOTAL TIME, BEST-OF Β· 36 FIXTURES Β· IO EXCLUDED

BlazeDiffOther librariesLower is better

Levels: blazediff stored Β· zune-png stored.

Apple M1 Max Β· darwin/arm64 Β· Node v22.14.0 Β· rustc 1.97.1 (8bab26f4f 2026-07-14) Β· best-of, iterations scaled by image size, single-threaded, Node (V8) running wasm32 with SIMD Β· 2026-10-26 Β· 3017cb8-dirty Β· pnpm benchmark png-wasm

Per-fixture results (36)
FixtureMPxblazediffzune-pngblazediff vs zune-png
4k/1a.png17.944.55ms71.50ms1.61x
4k/1b.png17.937.01ms66.31ms1.79x
4k/2a.png20.051.72ms81.47ms1.58x
4k/2b.png20.042.54ms74.70ms1.76x
4k/3a.png24.052.96ms91.61ms1.73x
4k/3b.png24.050.30ms94.01ms1.87x
alpha/1a.png0.00.09ms0.14ms1.60x
alpha/1b.png0.00.09ms0.14ms1.57x
blazediff/1a.png0.40.94ms1.50ms1.59x
blazediff/1b.png0.40.91ms1.50ms1.64x
blazediff/2a.png0.40.75ms1.19ms1.59x
blazediff/2b.png0.40.77ms1.22ms1.59x
blazediff/3a.png1.63.35ms6.20ms1.85x
blazediff/3b.png1.63.42ms5.85ms1.71x
blazediff/4a.png3.87.90ms13.80ms1.75x
blazediff/4b.png3.87.97ms13.63ms1.71x
page/1a.png58.9129ms258ms1.99x
page/1b.png58.9131ms264ms2.01x
page/2a.png41.789.78ms153ms1.71x
page/2b.png41.788.88ms156ms1.76x
pixelmatch/1a.png0.10.28ms0.45ms1.62x
pixelmatch/1b.png0.10.28ms0.47ms1.64x
pixelmatch/2a.png0.10.14ms0.24ms1.66x
pixelmatch/2b.png0.10.14ms0.23ms1.60x
pixelmatch/3a.png0.10.28ms0.45ms1.59x
pixelmatch/3b.png0.10.27ms0.46ms1.66x
pixelmatch/4a.png0.20.38ms0.61ms1.62x
pixelmatch/4b.png0.20.39ms0.63ms1.63x
pixelmatch/5a.png0.10.14ms0.24ms1.63x
pixelmatch/5b.png0.10.14ms0.23ms1.61x
pixelmatch/6a.png0.10.14ms0.22ms1.60x
pixelmatch/6b.png0.10.14ms0.22ms1.62x
pixelmatch/7a.png0.30.52ms0.85ms1.64x
pixelmatch/7b.png0.30.52ms0.86ms1.68x
same/1a.png1.73.58ms6.16ms1.72x
same/1b.png1.73.60ms6.16ms1.71x
TOTAL756ms1.37s1.82x

WebAssembly encode, default settings

TOTAL TIME, BEST-OF Β· 36 FIXTURES Β· IO EXCLUDED

BlazeDiffOther librariesLower is better

Levels: blazediff fdeflate, adaptive filter Β· zune-png stored Β· jSquash png crate default.

Apple M1 Max Β· darwin/arm64 Β· Node v22.14.0 Β· rustc 1.97.1 (8bab26f4f 2026-07-14) Β· best-of, iterations scaled by image size, single-threaded, Node (V8) running wasm32 with SIMD Β· 2026-10-26 Β· 3017cb8-dirty Β· pnpm benchmark png-wasm

Per-fixture results (36)
FixtureMPxblazediffzune-pngjSquashblazediff vs jSquashzune-png vs jSquash
4k/1a.png17.9236ms65.81ms286ms1.21x4.35x
4k/1b.png17.9225ms70.29ms276ms1.22x3.92x
4k/2a.png20.0234ms73.03ms308ms1.32x4.22x
4k/2b.png20.0240ms74.41ms303ms1.26x4.07x
4k/3a.png24.0304ms87.89ms384ms1.26x4.37x
4k/3b.png24.0304ms89.58ms388ms1.28x4.33x
alpha/1a.png0.00.16ms0.14ms0.23ms1.39x1.59x
alpha/1b.png0.00.16ms0.14ms0.23ms1.38x1.56x
blazediff/1a.png0.43.48ms1.50ms3.17ms0.91x2.11x
blazediff/1b.png0.43.44ms1.52ms3.18ms0.92x2.10x
blazediff/2a.png0.41.38ms1.20ms2.12ms1.53x1.76x
blazediff/2b.png0.41.40ms1.19ms2.14ms1.53x1.79x
blazediff/3a.png1.617.94ms6.10ms18.34ms1.02x3.00x
blazediff/3b.png1.617.72ms5.82ms17.91ms1.01x3.08x
blazediff/4a.png3.823.73ms13.54ms19.57ms0.82x1.44x
blazediff/4b.png3.823.81ms13.54ms19.55ms0.82x1.44x
page/1a.png58.9485ms233ms413ms0.85x1.77x
page/1b.png58.9480ms234ms404ms0.84x1.72x
page/2a.png41.7207ms157ms323ms1.56x2.05x
page/2b.png41.7191ms156ms321ms1.68x2.06x
pixelmatch/1a.png0.11.14ms0.44ms0.93ms0.82x2.10x
pixelmatch/1b.png0.11.19ms0.47ms0.96ms0.81x2.05x
pixelmatch/2a.png0.10.50ms0.24ms0.91ms1.83x3.87x
pixelmatch/2b.png0.10.49ms0.23ms0.89ms1.82x3.92x
pixelmatch/3a.png0.11.12ms0.45ms0.81ms0.73x1.79x
pixelmatch/3b.png0.11.12ms0.46ms0.82ms0.73x1.78x
pixelmatch/4a.png0.22.28ms0.62ms2.62ms1.15x4.26x
pixelmatch/4b.png0.22.28ms0.64ms2.75ms1.21x4.26x
pixelmatch/5a.png0.10.60ms0.24ms0.52ms0.87x2.19x
pixelmatch/5b.png0.10.57ms0.23ms0.52ms0.90x2.28x
pixelmatch/6a.png0.10.80ms0.22ms0.80ms1.00x3.59x
pixelmatch/6b.png0.10.79ms0.22ms0.74ms0.94x3.30x
pixelmatch/7a.png0.31.25ms0.85ms2.04ms1.63x2.41x
pixelmatch/7b.png0.31.22ms0.86ms2.06ms1.69x2.40x
same/1a.png1.712.78ms6.16ms10.73ms0.84x1.74x
same/1b.png1.712.82ms6.16ms10.69ms0.83x1.74x
TOTAL3.04s1.30s3.53s1.16x2.71x

WebAssembly encode size, no compression

TOTAL OUTPUT SIZE Β· 36 FIXTURES

BlazeDiffOther librariesLower is better

Levels: blazediff stored Β· zune-png stored.

Apple M1 Max Β· darwin/arm64 Β· Node v22.14.0 Β· rustc 1.97.1 (8bab26f4f 2026-07-14) Β· best-of, iterations scaled by image size, single-threaded, Node (V8) running wasm32 with SIMD Β· 2026-10-26 Β· 3017cb8-dirty Β· pnpm benchmark png-wasm

Per-fixture results (36)
FixtureMPxblazediffzune-pngblazediff vs zune-png
4k/1a.png17.968.4 MB68.5 MB99.9%
4k/1b.png17.968.4 MB68.5 MB99.9%
4k/2a.png20.076.2 MB76.3 MB99.9%
4k/2b.png20.076.2 MB76.3 MB99.9%
4k/3a.png24.091.6 MB91.7 MB99.9%
4k/3b.png24.091.6 MB91.7 MB99.9%
alpha/1a.png0.0144.3 KB144.5 KB99.9%
alpha/1b.png0.0144.3 KB144.5 KB99.9%
blazediff/1a.png0.41.6 MB1.6 MB99.9%
blazediff/1b.png0.41.6 MB1.6 MB99.9%
blazediff/2a.png0.41.3 MB1.3 MB99.9%
blazediff/2b.png0.41.3 MB1.3 MB99.9%
blazediff/3a.png1.66.2 MB6.2 MB99.9%
blazediff/3b.png1.66.2 MB6.2 MB99.9%
blazediff/4a.png3.814.4 MB14.5 MB99.9%
blazediff/4b.png3.814.4 MB14.5 MB99.9%
page/1a.png58.9224.9 MB225.2 MB99.9%
page/1b.png58.9224.9 MB225.2 MB99.9%
page/2a.png41.7159.1 MB159.4 MB99.9%
page/2b.png41.7159.1 MB159.4 MB99.9%
pixelmatch/1a.png0.1512.4 KB513.1 KB99.9%
pixelmatch/1b.png0.1512.4 KB513.1 KB99.9%
pixelmatch/2a.png0.1256.3 KB256.7 KB99.9%
pixelmatch/2b.png0.1256.3 KB256.7 KB99.9%
pixelmatch/3a.png0.1512.4 KB513.1 KB99.9%
pixelmatch/3b.png0.1512.4 KB513.1 KB99.9%
pixelmatch/4a.png0.2705.4 KB706.5 KB99.9%
pixelmatch/4b.png0.2705.4 KB706.5 KB99.9%
pixelmatch/5a.png0.1256.3 KB256.7 KB99.9%
pixelmatch/5b.png0.1256.3 KB256.7 KB99.9%
pixelmatch/6a.png0.1256.3 KB256.7 KB99.9%
pixelmatch/6b.png0.1256.3 KB256.7 KB99.9%
pixelmatch/7a.png0.3977.2 KB978.6 KB99.9%
pixelmatch/7b.png0.3977.2 KB978.6 KB99.9%
same/1a.png1.76.6 MB6.6 MB99.9%
same/1b.png1.76.6 MB6.6 MB99.9%
TOTAL1.28 GB1.28 GB99.9%

WebAssembly encode size, default settings

TOTAL OUTPUT SIZE Β· 36 FIXTURES

BlazeDiffOther librariesLower is better

Levels: blazediff fdeflate, adaptive filter Β· zune-png stored Β· jSquash png crate default.

Apple M1 Max Β· darwin/arm64 Β· Node v22.14.0 Β· rustc 1.97.1 (8bab26f4f 2026-07-14) Β· best-of, iterations scaled by image size, single-threaded, Node (V8) running wasm32 with SIMD Β· 2026-10-26 Β· 3017cb8-dirty Β· pnpm benchmark png-wasm

Per-fixture results (36)
FixtureMPxblazediffzune-pngjSquashblazediff vs jSquashzune-png vs jSquash
4k/1a.png17.919.9 MB68.5 MB25.8 MB76.9%265.1%
4k/1b.png17.918.4 MB68.5 MB24.5 MB74.9%278.9%
4k/2a.png20.028.0 MB76.3 MB37.1 MB75.5%205.4%
4k/2b.png20.028.1 MB76.3 MB37.1 MB75.5%205.3%
4k/3a.png24.035.5 MB91.7 MB43.2 MB82.1%212.3%
4k/3b.png24.035.1 MB91.7 MB42.8 MB82.0%214.5%
alpha/1a.png0.02.3 KB144.5 KB4.5 KB51.1%3235.1%
alpha/1b.png0.02.2 KB144.5 KB4.5 KB49.5%3187.0%
blazediff/1a.png0.467.9 KB1.6 MB152.5 KB44.5%1107.5%
blazediff/1b.png0.468.1 KB1.6 MB152.8 KB44.5%1105.5%
blazediff/2a.png0.419.6 KB1.3 MB77.8 KB25.2%1766.4%
blazediff/2b.png0.420.2 KB1.3 MB79.9 KB25.3%1720.1%
blazediff/3a.png1.6996.6 KB6.2 MB1.2 MB79.2%507.3%
blazediff/3b.png1.6978.8 KB6.2 MB1.2 MB79.0%515.2%
blazediff/4a.png3.8307.2 KB14.5 MB232.3 KB132.2%6376.4%
blazediff/4b.png3.8328.9 KB14.5 MB236.9 KB138.8%6254.4%
page/1a.png58.912.4 MB225.2 MB16.7 MB74.3%1349.0%
page/1b.png58.912.4 MB225.2 MB16.7 MB74.3%1350.0%
page/2a.png41.76.5 MB159.4 MB16.8 MB38.5%945.9%
page/2b.png41.76.5 MB159.4 MB16.9 MB38.4%944.9%
pixelmatch/1a.png0.137.0 KB513.1 KB40.0 KB92.5%1282.6%
pixelmatch/1b.png0.136.9 KB513.1 KB40.0 KB92.4%1283.7%
pixelmatch/2a.png0.144.9 KB256.7 KB122.3 KB36.7%209.9%
pixelmatch/2b.png0.146.0 KB256.7 KB124.7 KB36.9%205.9%
pixelmatch/3a.png0.127.8 KB513.1 KB33.6 KB82.8%1527.2%
pixelmatch/3b.png0.127.9 KB513.1 KB33.7 KB82.8%1521.9%
pixelmatch/4a.png0.2280.8 KB706.5 KB317.8 KB88.4%222.3%
pixelmatch/4b.png0.2299.9 KB706.5 KB338.2 KB88.7%208.9%
pixelmatch/5a.png0.114.6 KB256.7 KB43.5 KB33.5%589.8%
pixelmatch/5b.png0.113.9 KB256.7 KB42.6 KB32.6%602.1%
pixelmatch/6a.png0.182.7 KB256.7 KB105.0 KB78.7%244.5%
pixelmatch/6b.png0.165.5 KB256.7 KB87.5 KB74.9%293.4%
pixelmatch/7a.png0.351.2 KB978.6 KB144.8 KB35.4%675.9%
pixelmatch/7b.png0.350.5 KB978.6 KB143.2 KB35.3%683.6%
same/1a.png1.7206.3 KB6.6 MB306.2 KB67.4%2220.8%
same/1b.png1.7206.3 KB6.6 MB306.2 KB67.4%2220.8%
TOTAL206.8 MB1.28 GB283.2 MB73.0%462.5%

Switching

// Before import { decode, encode } from "@jsquash/png"; const imageData = await decode(arrayBuffer); const png = await encode(imageData); // After import { decode, encode } from "@blazediff/codec-png-wasm"; const image = await decode(new Uint8Array(arrayBuffer)); // { data, width, height } const out = await encode(image, { compression: 4 });

When to keep jSquash

  • You need 16-bit PNG output.
  • You already use other jSquash codecs and want one toolchain.
  • You need an ImageData object to draw on a canvas without a conversion step.
Last updated on