Zig-powered structural JSON diffing. Native speed via WebAssembly, with a pure JS fallback.
npm install @jsondelta/diff
import{diff}from'@jsondelta/diff'constdelta=diff({name: 'alice',role: 'viewer',tags: ['staff']},{name: 'alice',role: 'admin',tags: ['staff','elevated']})// [// { op: 'replace', path: ['role'], old: 'viewer', new: 'admin' },// { op: 'add', path: ['tags', 1], value: 'elevated' }// ]The default import automatically selects the fastest available backend: native addon, WebAssembly, or pure JS fallback. You can also import a specific backend directly:
import{diff}from'@jsondelta/diff/fallback'import{diff}from'@jsondelta/diff/wasm'import{diff}from'@jsondelta/diff'constbefore={title: 'Q1 Report',sections: [{heading: 'Revenue',body: 'Revenue grew 12% YoY.'},{heading: 'Costs',body: 'Operating costs remained flat.'}],status: 'draft'}constafter={title: 'Q1 Report',sections: [{heading: 'Revenue',body: 'Revenue grew 15% YoY, beating estimates.'},{heading: 'Costs',body: 'Operating costs remained flat.'}],status: 'review'}constchanges=diff(before,after)// [// { op: 'replace', path: ['sections', 0, 'body'],// old: 'Revenue grew 12% YoY.',// new: 'Revenue grew 15% YoY, beating estimates.' },// { op: 'replace', path: ['status'], old: 'draft', new: 'review' }// ]import{diff}from'@jsondelta/diff'constexpected=JSON.parse(fs.readFileSync('config.expected.json','utf8'))constactual=JSON.parse(fs.readFileSync('config.actual.json','utf8'))constdrift=diff(expected,actual)if(drift.length>0){console.log(`${drift.length} config values have drifted:`)for(constopofdrift){console.log(` ${op.path.join('.')}: ${JSON.stringify(op.old)} -> ${JSON.stringify(op.new)}`)}}diff(a, b) returns an array of operations:
| Operation | Fields | Description |
|---|---|---|
add | op, path, value | A value was added at path |
remove | op, path, value | A value was removed from path |
replace | op, path, old, new | The value at path changed |
Paths are arrays of keys (strings for object properties, numbers for array indices). The delta is reversible - remove and replace operations include the original values.
Identical inputs return an empty array [].
The diff engine is written in Zig and compiled to WebAssembly (68KB). When loaded, it parses both JSON values, walks the structure recursively, and emits a minimal set of operations describing the differences.
The pure JS fallback implements the same algorithm for environments where WebAssembly is not available.
Architecture:
- WebAssembly - Zig compiled to wasm32-freestanding. Near-native speed, runs in Node.js and browsers
- Pure JS fallback - Zero-dependency, always works. Same algorithm, same output
MIT