Pixel-by-pixel Comparison with Node Native
@blazediff/core-native is the fastest way to diff two images from Node. It
is the Rust core compiled to a Node addon through N-API, with SIMD in both passes.
Unlike the JS and wasm cores it also handles the file layer: it accepts paths or
encoded buffers, decodes PNG, JPEG and QOI itself, and writes the diff image to
disk for you.
Reach for it in test runners and CI, which is where the decode cost and the per-run overhead actually add up. It needs a prebuilt binary for the platform, so it is not an option in browsers or on the edge. That is what the wasm build is for.
Installation
npm install @blazediff/core-nativePlatform binaries ship as optional dependencies for macOS, Linux and Windows on
x64 and arm64. There is no build step and no node-gyp.
Examples
Basic Comparison

Image 1

Image 2
Result
import { compare } from "@blazediff/core-native";
const result = await compare("3a.png", "3b.png");
if (result.match) {
console.log("identical");
} else if (result.reason === "pixel-diff") {
console.log(`${result.diffCount} pixels differ (${result.diffPercentage.toFixed(2)}%)`);
} else if (result.reason === "layout-diff") {
console.log("dimensions differ");
}Encoded inputs are borrowed directly for each native call, so the JavaScript bytes are never copied into Rust. Decoding still allocates native RGBA buffers, and on a 4K pair that decode is the larger share of the total.
What it costs
Against odiffΒ on the same fixtures with image IO included, measured with hyperfine on an M1 Max, 25 runs:
| Case | odiff | @blazediff/core-native |
|---|---|---|
| 4K pair | 1157.12-1677.13ms | 288.01-349.43ms |
| 4K pair, identical | 269.36-366.79ms | 183.94-230.29ms |
That is 4x to 4.8x on a changed 4K pair. Because decode dominates end-to-end time, passing already-decoded buffers moves the number further than any change to the diff kernel would. Full tables.
Next
- Want a verdict on what changed rather than how many pixels? Reach for
@blazediff/interpret-nativeor read Image difference analysis - Wiring this into Jest, Vitest or Bun:
@blazediff/vitestreference - Every option and its default:
@blazediff/core-nativereference