Compare two JSON payloads structurally and read every added, removed or retyped key by its path, beside a unified view of the merged document.
Two payloads that differ in a single value can look completely unrelated to a line-based diff, because whatever wrote the second one sorted the keys and reindented the file on its way out. JSON Diff Checker compares the parsed structures rather than the characters. Key order stops mattering. Whitespace stops mattering. What survives is a list of the paths whose values genuinely moved.
Each difference is reported in two shapes, because the two answer different questions. The change list names every one by JSON path, so $.env.LOG_LEVEL tells you where to look in a 400-line manifest without scrolling for it. The unified view redraws the merged document with deleted lines marked − and inserted lines marked +, which is the shape you already read in a pull request.
Arrays are where comparers usually go wrong. A slot-by-slot match is correct for an ordered list and badly wrong for a set of feature flags that some serialiser shuffled, so one toggle switches to matching items by value instead. Parsing happens in the JavaScript engine already running this page. A production config with live credentials in it goes nowhere.
Press Load Sample and two revisions of the same service manifest drop in. Both open on "service": "checkout-api". The original sits at "version": "2.4.0" with 3 replicas; the modified one reads "2.5.1" and asks for 5. Four stat cards settle on 2 added, 1 removed, 3 changed, 5 identical.
The change list spells out which is which. $.env.RETRIES and $.features[2] are the two additions. The single deletion is $.owner.oncall, which held ana.ruiz@harbourline.dev before someone dropped the field. The three edits are the version string, the replica count, and $.env.LOG_LEVEL moving from info to debug. Five paths matched on both sides and stay hidden until you ask to see them.
["x","y","z"] against ["z","y","x"] reports nothing instead of two edits. Only real insertions and deletions survive it.INFO on one side from reading as a change.$.owner.oncall and that path alone lands on your clipboard, ready to paste into a jq expression or a test assertion. Almost nobody discovers this on a first visit.JSON.parse keeps the last value silently. Both boxes are scanned for this before the comparison runs, and {"x": 1, "x": 2} raises an amber notice naming the key, because the value you wrote first is already gone by the time any diff sees it.1 and 1.0 are reported as identical. Both parse to the same double, and JSON carries no separate integer type to tell them apart.9007199254740993 arrives as ...992 and two different record IDs can compare as unchanged. A warning names the first literal it finds."8080" against 8080 is one change tagged string to number, not a deletion plus an addition.Each side is capped at 200,000 characters. Trim this payload and paste it again. and the comparison stops rather than freezing the tab.Added
2
Removed
1
Changed
3
Identical
5
− "2.4.0"
+ "2.5.1"
− 3
+ 5
− "info"
+ "debug"
+ 2
+ "klarna"
− "ana.ruiz@harbourline.dev"