JSON Diff / Structural Compare

Compare two JSON documents key by key and see exactly what was added, removed or changed.

100% client-side

JSON A (original)

0 characters

JSON B (modified)

0 characters

Differences

Added Removed Changed
Paste JSON in both panels (or click Example) to compare them.

What is JSON Diff / Structural Compare?

A text diff (like the one in git diff) compares two files line by line, so reformatting a JSON document — reindenting it, or writing the same keys in a different order — looks like a wall of changes even when nothing meaningful actually changed. This tool instead parses both documents and compares them structurally, key by key and value by value, so only real differences show up: keys that were added or removed, and values whose content or type changed.

How to use JSON Diff / Structural Compare

  1. Paste the original JSON into the JSON A panel, and the modified version into JSON B — or click Example to load a sample pair.
  2. The Differences panel below builds a collapsible tree automatically, with added, removed and changed entries color-coded.
  3. Toggle Ignore key order or Ignore array element order if your two documents are expected to differ only in ordering.
  4. Use Expand all / Collapse all to control how much of the tree is visible.

How the structural comparison works

Every key present in either document is visited once. A key that exists in both sides is compared recursively — objects and arrays are walked into, primitive values are compared directly. A key missing from one side is marked added or removed; a value present on both sides that differs is marked changed, with the JSON type of each side shown separately so a type change (like the number 5 becoming the string "5") is never confused with an ordinary value change:

// A                          // B
{                              {
  "active": true,                "active": false,   ← changed (value)
  "score": 88,                   "score": "88",      ← changed (type: number → string)
  "legacy": true,                                     ← removed
                                  "verified": true,    ← added
  "roles": ["admin", "dev"]      "roles": ["dev", "admin", "owner"]
}                              }

Array comparison is by index, not by guessing which elements "moved": element 0 of A is compared to element 0 of B, element 1 to element 1, and so on. This is simple, predictable and matches how most real-world JSON (API responses, config snapshots) is meant to be compared — but it means inserting an element in the middle of an array shifts every following index, which shows up as several changed entries rather than a single clean "insertion." Turning on Ignore array element order switches to matching array elements by equal value regardless of position, so a pure reordering correctly shows as no change, at the cost of no longer distinguishing "moved" from "removed and re-added elsewhere." To keep the tab responsive on very large diffs, the tree stops after the first 200 differences and shows a note with the true total instead of rendering everything.

Frequently asked questions

How is this different from a line-by-line text diff?

A text diff compares raw lines, so re-indenting or reformatting JSON (without changing any value) shows as a wall of changes. This tool parses both documents and compares them by key and value, so formatting differences never matter — only real structural differences do.

How does it compare arrays?

By index: element 0 of A is compared to element 0 of B, and so on. This is simple and predictable for the common case (comparing two API responses or config snapshots), but it means inserting an element in the middle of an array shifts every element after it, showing up as several changed entries instead of one insertion. Turn on "Ignore array order" to instead match elements by equal value regardless of position, which correctly shows a pure reordering as no change at all.

What counts as a changed value?

Two things: the value itself changing (e.g. 88 to 92) and the JSON type changing (e.g. the number 5 becoming the string "5"). Both are marked as changed, but a type change is shown with each side's type labeled, like (number) 5 → (string) "5", so you can tell them apart at a glance.

Is there a limit on how large the JSON can be?

The comparison itself handles thousands of keys quickly, but rendering every single difference as DOM nodes would freeze the tab on a huge diff. Past 200 differences, the tree shows the first 200 and a note telling you how many more exist so you can narrow your input.