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 odiff

BlazeDiff vs odiff

@blazediff/core-native is ~2.5x faster than odiff over our 34 fixtures, with image decode and diff PNG writing included. Both are native binaries with a Node API, and both return the same kind of result, so most code moves over with a changed import.

odiff is a SIMD image diff written in Zig, popular in visual testing tools. It decodes many image formats and has a server mode that keeps one process alive between comparisons. BlazeDiff runs a block-based Rust kernel with SIMD on ARM and x86, and it reads file paths or encoded bytes.

At a glance

odiffBlazeDiff (core-native)
LicenseMITMIT
ImplementationZig, SIMD (SSE2, AVX2, AVX512, NEON)Rust, SIMD (NEON, SSE4.1)
DeliveryNative binary, Node API, CLIN-API addon, @blazediff/cli, Python, Rust
InputFile paths, buffersFile paths, encoded bytes
FormatsPNG, JPEG, WebP, TIFF, BMPPNG, JPEG, QOI
Color metricYIQYIQ
Ignore regionsYes (rectangles)No (selector masks in @blazediff/agent)
Browser / edgeNoYes, through @blazediff/core-wasm
Beyond pixel countsChanged lines and columnsRegion analysis, SSIM, GMSD and MILO packages

Benchmarks

odiff runs through ODiffServer, its server mode, so process start-up is not counted against it. β€œBlazeDiff Next” is the same binary with the blazediff-png codec turned on through BLAZEDIFF_PNG_ENABLED=1.

JavaScript Native Binary (@blazediff/core-native vs odiff) (image IO included)

TOTAL TIME Β· 34 FIXTURES Β· MEAN OF 25 RUNS Β· IO INCLUDED

BlazeDiffOther librariesLower is better

Apple M1 Max Β· darwin/arm64 Β· Node v22.14.0 Β· rustc 1.97.1 (8bab26f4f 2026-07-14) Β· 2026-10-22 Β· 234b300-dirty Β· pnpm benchmark core-native

Per-fixture results (34)
FixtureODiffBlazeDiffBlazeDiff NextBlazeDiff vs ODiffBlazeDiff Next vs ODiff
4k/11.30s316ms233ms4.09x5.55x
4k/1 (identical)271ms187ms150ms1.45x1.81x
4k/21.56s393ms313ms3.97x4.99x
4k/2 (identical)338ms224ms167ms1.50x2.02x
4k/31.89s393ms300ms4.80x6.30x
4k/3 (identical)389ms231ms175ms1.69x2.23x
blazediff/13.92ms3.08ms2.97ms1.27x1.32x
blazediff/1 (identical)1.53ms0.87ms0.85ms1.75x1.81x
blazediff/24.29ms3.57ms2.06ms1.20x2.08x
blazediff/2 (identical)1.39ms1.06ms0.76ms1.31x1.83x
blazediff/348.95ms32.15ms20.54ms1.52x2.38x
blazediff/3 (identical)18.79ms14.28ms11.42ms1.32x1.64x
blazediff/423.79ms26.31ms23.92ms0.90x0.99x
blazediff/4 (identical)10.93ms4.61ms3.80ms2.37x2.87x
page/1998ms675ms548ms1.48x1.82x
page/1 (identical)542ms249ms166ms2.18x3.27x
page/2607ms415ms280ms1.46x2.17x
page/2 (identical)124ms42.18ms32.85ms2.93x3.76x
pixelmatch/13.84ms2.23ms1.21ms1.72x3.16x
pixelmatch/1 (identical)1.73ms1.05ms0.84ms1.64x2.05x
pixelmatch/23.54ms1.79ms1.72ms1.98x2.06x
pixelmatch/2 (identical)0.53ms0.47ms0.22ms1.12x2.40x
pixelmatch/33.25ms1.42ms1.30ms2.28x2.49x
pixelmatch/3 (identical)1.67ms0.87ms0.63ms1.91x2.65x
pixelmatch/49.61ms4.85ms4.72ms1.98x2.04x
pixelmatch/4 (identical)2.64ms2.16ms1.25ms1.22x2.11x
pixelmatch/50.79ms0.97ms0.70ms0.82x1.14x
pixelmatch/5 (identical)0.85ms0.56ms0.41ms1.52x2.08x
pixelmatch/68.90ms2.08ms2.39ms4.29x3.73x
pixelmatch/6 (identical)0.98ms0.83ms0.57ms1.18x1.71x
pixelmatch/73.60ms2.64ms1.80ms1.36x2.00x
pixelmatch/7 (identical)0.72ms0.63ms0.31ms1.15x2.36x
same/15.04ms3.09ms2.95ms1.63x1.71x
same/1 (identical)5.50ms3.20ms2.58ms1.72x2.13x
TOTAL8.18s3.24s2.45s2.52x3.33x

Switching

The result is a discriminated union in both libraries: match, then a reason of layout-diff, pixel-diff or file-not-exists, with diffCount and diffPercentage on a pixel diff.

// Before import { compare } from "odiff-bin"; // After import { compare } from "@blazediff/core-native"; const result = await compare("baseline.png", "current.png", "diff.png", { threshold: 0.1, antialiasing: true, }); if (!result.match && result.reason === "pixel-diff") { console.log(`${result.diffCount} pixels differ`); }

odiff options such as ignoreRegions, captureDiffLines and reduceRamUsage have no direct counterpart. Remove them, or mask the regions before the diff.

When to keep odiff

  • You compare WebP, TIFF or BMP files, or a JPEG against a PNG.
  • You depend on ignoreRegions or on the changed-line output.
  • You use a tool that already integrates odiff, for example Argos or Lost Pixel.
Last updated on