JSON Diff

Compare two JSON documents and see exactly which keys were added, removed or changed, structurally rather than as lines of text.

0
Added
0
Removed
0
Changed
Paste two JSON documents to compare them.

Objects are compared as sets. Arrays are compared as index maps.

Reordering the keys of an object reports nothing, which is correct — JSON objects are unordered, so two documents differing only in the order their keys were written are the same document. The diff walks the union of both key sets rather than comparing positions, so this holds at any depth.

LeftRightChanges
{"a":1,"b":2}{"b":2,"a":1}0
{"a":{"p":1,"q":2}}{"a":{"q":2,"p":1}}0
{"x":1,"y":2,"z":3}{"z":3,"y":2,"x":1}0

Arrays get the opposite treatment. They are compared index by index, so an element inserted at the front shifts everything after it and each shifted element reports as changed:

Edit to [1,2,3,4,5]ResultChanges
insert at front[0,1,2,3,4,5]6
insert at end[1,2,3,4,5,6]1
remove first[2,3,4,5]5
remove last[1,2,3,4]1
reverse[5,4,3,2,1]4

The same edit — adding one element — costs 1 change at the end and 6 at the front. Nothing is wrong; index-by-index is what comparing two arrays means unless you go looking for a longest common subsequence, which costs far more to compute and guesses at intent. But a six-line diff on a reordered list is not six problems, and it is worth knowing which one you are reading.

A small tell: reversing [1,2,3] gives 2 changes, not three. The middle element never moved. Reversing the same three values written as object keys gives 0.

And the parser got there first

The comparison runs on parsed values, so anything JSON.parse discarded is invisible before the diff starts. Every pair below is different text and the same data:

What differsLeftRightChanges
trailing zero {"a":1} {"a":1.0} 0
exponent form {"a":1} {"a":1e0} 0
duplicate key {"a":1,"a":2} {"a":2} 0
whitespace {"a":1} { "a" : 1 } 0
escaped character {"a":"x"} {"a":"\u0078"} 0

That is a feature for comparing data and a trap for comparing files. If you want to know whether two files are byte-identical this is the wrong tool; if you want to know whether two APIs returned the same thing, it is the right one. (What JSON does to large numbers before you get here is its own story, on this site's JSON formatter.)

A type change is one change, not a tree

ChangeLeftRightChanges
object becomes a number {"a":{"b":{"c":1}}} {"a":1} 1
array becomes an object {"a":[1,2,3]} {"a":{"0":1}} 1
null becomes an object {"a":null} {"a":{}} 1
string becomes a number {"a":"1"} {"a":1} 1

When the two sides are different types the walk stops and reports a single line — replacing a three-level nested object with the number 1 is one row of output, not a list of everything that vanished. And null is given its own type rather than being lumped in with objects, which matters because typeof null is "object" in JavaScript and a naive walk would try to enumerate its keys.

How to use

  1. Paste the original document on one side and the new one on the other.
  2. Read the added, removed and changed keys.
  3. Expand a path to see the old and new values.
  4. Sort keys first if the two came from different sources.

Frequently asked questions

Why not just use a text diff?

Because JSON is a structure, not lines. Reformatting or reordering keys changes every line of a text diff while changing nothing about the data. A structural comparison reports only genuine differences, which is usually what you want to know.

Does key order matter?

Not to the data — JSON objects are unordered by specification, so two documents differing only in key order hold identical information. It matters a great deal to a text diff, which is exactly why a structural comparison is the right tool here.

How are arrays compared?

This is the hard part, because arrays are ordered and an inserted element shifts everything after it. Comparing by position reports one insertion as a change to every subsequent element. Comparing by identity is more useful but needs to know which field identifies a record.

What is a JSON Patch?

A standard format describing the changes needed to turn one document into another, as a list of add, remove, replace, move and copy operations. It is designed to be applied programmatically, which makes it useful for syncing rather than just for reading.

Does my data get uploaded?

No. Both documents are compared entirely in your browser. That matters for API responses, configuration and anything containing credentials or personal data.

Why does a number show as changed when it looks the same?

Usually floating-point representation. A value that reads as 0.1 in one document may have been stored with slightly different precision in the other, or an integer may have been parsed as a float. Very large integers lose precision in JSON parsing, which produces exactly this symptom.

🔒 This tool runs entirely in your browser. Nothing you enter is uploaded, logged, or stored.