Tools
Guides

JSON Diff

JSON

Compare two JSON documents and highlight structural differences.

100% client-side No backend
Left (original)
Right (changed)
Output
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#

  1. Paste the original document into the Left (original) pane and the revised one into the Right (changed) pane.
  2. The comparison runs live as you type. You can also click Compare to force a refresh.
  3. 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 $.version or $.tags[2], so you can locate it in either document.
  4. If both documents are deeply equal, the status line says so explicitly — “no differences” — rather than leaving an empty pane to interpret.
  5. 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, .key for 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.