JSON Diff Libraries — Best Tools for Diffing JSON in JavaScript and Python
Several libraries make JSON diffing easier than writing your own. Here's a comparison of the best JavaScript and Python JSON diff libraries — fast-json-patch, jsondiffpatch,...
Several well-maintained libraries handle JSON diffing better than rolling your own. They handle edge cases (arrays, types, nested objects) and produce structured output you can act on.
Use the JSON Diff Tool to compare JSON documents visually without installing anything.
JavaScript libraries
fast-json-patch
The most popular RFC 6902 JSON Patch library. Generates and applies JSON Patch operations.
npm install fast-json-patch
import { compare, applyPatch, validate } from 'fast-json-patch';
const original = { a: 1, b: { c: 2 }, tags: ['x', 'y'] };
const updated = { a: 2, b: { c: 2, d: 3 }, tags: ['x'] };
// Generate patch:
const patch = compare(original, updated);
// [
// { op: 'replace', path: '/a', value: 2 },
// { op: 'add', path: '/b/d', value: 3 },
// { op: 'remove', path: '/tags/1' }
// ]
// Apply patch:
const result = applyPatch(original, patch).newDocument;
// Validate patch is applicable:
const errors = validate(patch, original);
Best for: REST APIs, RFC 6902 compliance, server-side state patching.
jsondiffpatch
Richer diff format with delta encoding. Shows arrays as sequences of additions/deletions.
npm install jsondiffpatch
import { diff, patch, reverse, formatters } from 'jsondiffpatch';
const a = { name: 'Alice', scores: [10, 20, 30] };
const b = { name: 'Bob', scores: [10, 25, 30, 40] };
const delta = diff(a, b);
// {
// name: ['Alice', 'Bob'], // [old, new]
// scores: { 1: [20, 25], 3: [40, 0, 0] } // [old, new] or [new, 0, 0] for added
// }
// Apply:
const result = patch(a, delta); // { name: 'Bob', scores: [10, 25, 30, 40] }
// Reverse the diff (undo):
const reversed = reverse(delta);
const original = patch(b, reversed);
// HTML visualization:
console.log(formatters.html.format(delta, a));
// Console visualization:
formatters.console.log(delta);
Best for: visual diffs, undo/redo systems, collaborative editing.
lodash isEqual + custom diff
For simple deep equality without a library:
import { isEqual, get, set, keys } from 'lodash';
function deepDiff(a, b, prefix = '') {
const diff = {};
const allKeys = [...new Set([...keys(a), ...keys(b)])];
for (const key of allKeys) {
const path = prefix ? `${prefix}.${key}` : key;
if (!isEqual(a[key], b[key])) {
if (typeof a[key] === 'object' && typeof b[key] === 'object'
&& !Array.isArray(a[key]) && !Array.isArray(b[key])) {
Object.assign(diff, deepDiff(a[key], b[key], path));
} else {
diff[path] = { from: a[key], to: b[key] };
}
}
}
return diff;
}
microdiff
Tiny (1KB), fast, no dependencies:
npm install microdiff
import diff from 'microdiff';
const original = { a: 1, b: { c: 2 } };
const updated = { a: 2, b: { c: 3, d: 4 } };
diff(original, updated);
// [
// { type: 'CHANGE', path: ['a'], value: 2, oldValue: 1 },
// { type: 'CHANGE', path: ['b', 'c'], value: 3, oldValue: 2 },
// { type: 'CREATE', path: ['b', 'd'], value: 4 }
// ]
Change types: CREATE, REMOVE, CHANGE.
Python libraries
deepdiff
The most feature-rich Python JSON diff library:
pip install deepdiff
from deepdiff import DeepDiff
original = {"name": "Alice", "scores": [10, 20, 30], "active": True}
updated = {"name": "Bob", "scores": [10, 25, 30, 40]}
diff = DeepDiff(original, updated)
print(diff)
# {
# 'values_changed': {
# "root['name']": {'new_value': 'Bob', 'old_value': 'Alice'},
# "root['scores'][1]": {'new_value': 25, 'old_value': 20}
# },
# 'iterable_item_added': {"root['scores'][3]": 40},
# 'dictionary_item_removed': {"root['active']"}
# }
# Get a simpler view:
diff.to_dict()
# Ignore order in lists:
DeepDiff(original, updated, ignore_order=True)
# Ignore specific types of changes:
DeepDiff(original, updated, exclude_types=[int])
# Generate a JSON-serializable report:
import json
json.loads(diff.to_json())
jsonpatch
RFC 6902 implementation for Python:
pip install jsonpatch
import jsonpatch
original = {"a": 1, "b": 2, "c": [1, 2, 3]}
updated = {"a": 10, "c": [1, 2]}
# Generate patch:
patch = jsonpatch.make_patch(original, updated)
print(patch.to_string())
# [{"op": "replace", "path": "/a", "value": 10},
# {"op": "remove", "path": "/b"},
# {"op": "remove", "path": "/c/2"}]
# Apply patch:
result = patch.apply(original)
# {"a": 10, "c": [1, 2]}
# Apply from string:
jsonpatch.apply_patch(original, '[{"op": "add", "path": "/d", "value": 4}]')
jsondiff
Simple, readable diff format:
pip install jsondiff
from jsondiff import diff, patch
a = {"x": 1, "y": [1, 2, 3]}
b = {"x": 2, "y": [1, 4, 3], "z": 5}
d = diff(a, b)
# {'x': 2, 'y': {1: 4}, 'z': 5}
# Missing keys = removed, new keys = added, shared = changed
# Apply:
result = patch(a, d)
Choosing a library
| Library | Language | Format | Use Case |
|---|---|---|---|
| fast-json-patch | JS | RFC 6902 | REST APIs, HTTP PATCH |
| jsondiffpatch | JS | Delta | Visual diffs, undo/redo |
| microdiff | JS | Custom | Simple, small bundle |
| deepdiff | Python | Custom | Analysis, reporting |
| jsonpatch | Python | RFC 6902 | REST APIs |
| jsondiff | Python | Delta | Readable diffs |
Related tools
- JSON Diff Tool — compare JSON visually without installing anything
- JSON Patch RFC 6902 — the standard patch format
- Compare JSON Objects — deep equality checks
Related posts
- Comparing JSON Structurally (Not Just as Strings) — Two JSON documents can be byte-different and semantically identical. Or byte-ide…
- How to Compare JSON Objects — Deep Equality and Diff in JavaScript and Python — Comparing JSON objects with == won't work for deep equality. Here's how to deep-…
- Detecting Changes in JSON Data — Audit Logs, Diffs, and Change Tracking — Detecting what changed in a JSON document is essential for audit logs, versionin…
- JSON Diff Tool — Compare Two JSON Objects and Find Differences — A JSON diff tool compares two JSON structures semantically, not textually. It fi…
- JSON Patch (RFC 6902) — Operation-Based JSON Document Updates — JSON Patch (RFC 6902) defines a sequence of operations (add, remove, replace, mo…
Related tool
Compare two JSON objects structurally with field-by-field diff.
Written by Mian Ali Khalid. Part of the Data & Format pillar.