Compare two JSON documents by structure rather than by line. Reports added, removed and changed paths, with an option to ignore array order. Runs entirely in your browser.
Compare by structure, not by line. Paste two documents and get a path-by-path report of what was added, removed or changed. Because the comparison walks the parsed values, reformatting or key reordering does not show up as a difference.
–
Differences
Why a text diff is the wrong tool for JSON
Line diffs see formatting, not meaning
A standard line-based diff treats JSON as prose. Re-indent a file from two spaces to four and every line is marked as changed. Move a key from the top of an object to the bottom and you get one deletion plus one insertion, even though the parsed value is exactly the same. Wrap a long array onto a single line and the entire block lights up.
A structural diff parses both sides first and then walks the resulting values. Formatting, key order and whitespace are gone by the time the comparison starts, so the only things that can be reported are genuine differences in the data. That is what makes the output short enough to actually read.
Paths, not line numbers
Each difference here is reported against a path such as user.roles[2] or meta.updated. A path survives edits elsewhere in the document, which a line number does not, so you can paste the same report into a ticket or a code review and it still points at the right place a week later.
The three operations map onto what can actually happen to a tree. A key present on the left but not the right is a removal, the reverse is an addition, and a key present on both with a different value is a change. Type changes — a field that used to be the number 1 and is now the string "1" — are reported as changes too, and they are worth paying attention to, because they are a common source of downstream bugs that no schema check catches.
Arrays and the ordering question
Arrays are where structural diffing gets opinionated. By default the comparison is positional: index 0 on the left is compared with index 0 on the right. That is correct for ordered data such as a sequence of steps, but it produces a misleading result for a list that is really a set — reorder the elements and every position looks changed.
The ignore-array-order option canonicalises both sides by sorting arrays deeply before comparing, so a reordered list compares as equal. Use it for tag lists, permission sets and query results with no guaranteed ordering. Leave it off whenever the position of an element carries meaning, because with it on, a genuine reordering bug becomes invisible.
FAQ
How is this different from a normal text diff?
A text diff compares lines, so reindenting or reordering keys shows up as a change. This tool parses both sides first, so only real differences in the data are reported.
What do the +, - and ~ symbols mean?
Plus is a path present only in the modified document, minus is present only in the original, and tilde is a path present in both with a different value.
Why is a reordered array reported as changed?
By default arrays are compared position by position, which is correct for ordered data. Turn on ignore array order to compare them as unordered sets instead.
Does key order in an object matter?
No. Objects are compared by key, so moving a field within an object never produces a difference. Only array element positions are order-sensitive.
Is a number that became a string flagged?
Yes. A type change is reported as a change, which is deliberate: 1 and "1" behave very differently downstream and the mismatch is easy to miss otherwise.
Are my documents sent to a server?
No. Both sides are parsed and compared in your browser, so nothing is uploaded, logged or stored.