JSON Diff
JSONCompare two JSON documents and highlight structural differences.
On this page
What is a JSON diff?#
A JSON diff compares two JSON documents and tells you exactly what changed between them — which fields appeared, which disappeared, and which kept the same path but took a different value. It is the structural equivalent of a text diff, but instead of matching lines it walks the object and array tree, so a value moving from 1 to 2 shows up as a precise edit at a specific path, not as a rewritten block of text.
This matters whenever JSON is the wire format for something that evolves: API responses between deploys, configuration files between revisions, fixtures in a test suite, exported data between days. Staring at two pretty-printed blobs side by side only works for tiny documents; the moment nesting gets deep, you need the differences enumerated.
The catch is that JSON diff is order-sensitive for arrays. Two arrays are equal only if their elements match position by position, because that is how JSON itself defines equality. So [a, b] and [b, a] are different, and the diff will report it — useful when order is meaningful (a sequence of steps), surprising when it is not (a set masquerading as an array).
How to use it#
- Paste the original document into the Left (original) pane and the revised one into the Right (changed) pane.
- The comparison runs live as you type. You can also click Compare to force a refresh.
- The output area lists each difference on its own row:
- Added — the path exists only on the right; the row shows the new value.
- Removed — the path exists only on the left; the row shows the old value.
- Changed — the path exists on both sides but with a differing value; the row shows
old → new. Each row is prefixed with a JSONPath-style path like$.versionor$.tags[2], so you can locate it in either document.
- If both documents are deeply equal, the status line says so explicitly — “no differences” — rather than leaving an empty pane to interpret.
- Sample loads a realistic before/after pair; Clear resets both panes and the result.
Key features#
- Structural, not textual. Compares the parsed value tree, so re-indenting, reordering object keys, or changing whitespace never produces a false difference.
- Precise paths. Every change carries its location in JSONPath notation —
$for the root,.keyfor object fields,[i]for array indices — so you can jump straight to the right spot. - Three change kinds. Added, removed, and changed are reported separately and colour-coded, so additions stand out from deletions and edits at a glance.
- Per-side error reporting. If one input is not valid JSON, the status line names which side failed (
Left input is not valid JSON.) instead of failing opaquely. - Live comparison. The diff updates as you edit either pane, so iterating on a fixture or response is immediate.
Worked example#
Load Sample and the two panes fill with a small configuration document before and after a revision:
{
"name": "ArpGate",
"version": 1,
"tags": ["json", "encoding"],
"features": { "static": true, "backend": null }
}
on the left, against:
{
"name": "ArpGate",
"version": 2,
"tags": ["json", "encoding", "crypto"],
"features": { "static": true, "backend": false, "offline": true }
}
on the right. The diff enumerates exactly what moved:
changed $.version 1 → 2
added $.tags[2] "crypto"
changed $.features.backend null → false
added $.features.offline true
Note what does not appear: $.name (unchanged), $.tags[0] and $.tags[1] (unchanged), and $.features.static (unchanged). Equal branches produce no output, so a four-line diff is the complete story even though both documents have several fields. If you then set both panes to the same document, the status line switches to “no differences — inputs are identical”.
FAQ#
Why does a reordered array show as fully changed?#
JSON arrays are ordered, and equality is positional. [1, 2] and [2, 1] differ at index 0 and index 1, so the diff reports two changes. That is correct for sequences where order is meaningful. If your array represents a set, sort it (or normalise it) in both documents before comparing — otherwise moves will look like edits.
Does it notice when an object key is renamed?#
It reports it as a removal plus an addition, because JSON has no way to express “this key became that key”. Renaming enabled to active shows up as removed $.enabled and added $.active — two rows, not one “rename”. That is the honest representation of what changed in the data.
What does a type change look like?#
It is reported as a single changed row. If a value goes from the string "36" to the number 36, the diff shows "36" → 36 at that path — the differing serialisations make the type flip visible. The same applies to null becoming false, or a number becoming an object.
Can it tell me which fields are unchanged?#
No, and on purpose. Listing every unchanged field would drown the actual changes in noise on any real document. The diff shows only the deltas; equal branches stay silent. If you need the full shape of one document, render it with the tree viewer.