Why compare JSON as data
A line diff of two JSON files reports a reordered key, a re-indented block or a trailing comma as a change, so the one value that matters hides among dozens that do not. This page parses both sides and compares the data they describe. A value that differs, or a key that was added or removed, is a change. Order and layout are not.
It opens with a sample loaded. Replace either side with your own document: two API responses, two configuration files, two exports of the same records. Both stay in your browser, and the comparison updates as you type.
What it reports
Same data, different layout
{"id": 42, "name": "Asha", "active": true}{
"active": true,
"id": 42,
"name": "Asha"
}No changes. The keys and values are identical; only their order and the whitespace between them differ.
Array items matched by id
[
{"id": 1, "role": "admin"},
{"id": 2, "role": "viewer"}
][
{"id": 2, "role": "editor"},
{"id": 1, "role": "admin"}
]One change, the role of item 2 from viewer to editor, and one move. The items are matched by id, so the reorder is not reported as items removed and added again.
A number that became a string
{"port": 8080}{"port": "8080"}Flagged as a type change, number to string. A line diff shows only two extra quotes, but many parsers and validators treat the two values differently.
Options
- Match arrays
- Automatic looks for a field that is unique on every item:
id,_id,uuid,key,code,slug,skuorname. You can name a different field, or match strictly by position when order is the point. - Ignore a path
- Any change row can be ignored, and everything under that path stops counting. A
/updatedAtor/meta/requestIdthat differs on every call is the usual candidate. - Noise
- Timestamps, UUIDs, hashes, JWTs, IP addresses and request IDs that differ are labelled noise and counted apart, so a response that changed only in those reads as unchanged at a glance.
- Compare this block
- Select an object or array in the tree and compare only that part of the two documents, on its own, when the rest of each file is not what you are checking.
- Copy as JSON Patch
- The whole difference as RFC 6902 operations that turn the left document into the right one, with ignored paths left out.
In a terminal
diff -u <(jq -S . old.json) <(jq -S . new.json)
jq -Sprints each file with the keys of every object sorted, so key order stops counting beforediffcompares the text. On this page's sample it leaves the three changed values, the addedcardVaultand theupdatedAttimestamp.diff <(jq -c 'tostream | select(length == 2)' old.json | sort) <(jq -c 'tostream | select(length == 2)' new.json | sort)
Prints every value on one line with its full path, such as
[["features","betaCheckout"],false], so each difference says where it is.paths(scalars)looks like a shorter way to do this, but it skips values that arefalseornull, and on this sample it losesbetaCheckout.
- What the page does that these do not
- jq compares arrays position by position, so two items that swapped places are two changed values, and it gives the
updatedAttimestamp the same weight as the timeout, where the page matches array items by an id field and counts the timestamp as noise. - What the terminal does better
- It copes with files far past the page's 5 MB a side: on two 33 MB files, sorting both with jq and comparing them with
git diff --no-indextook under three seconds. macOS's owndiffhad not finished the same pair after ten minutes, so at that size usegit diff.
<( ) is process substitution: it works in bash and zsh, not in plain sh. jq is built into current macOS as /usr/bin/jq, and it exits with 5 on a file that is not valid JSON.
Questions
Does key order matter in JSON?
Not to the data. The JSON standard defines an object as an unordered collection of name and value pairs, so {"a": 1, "b": 2} and {"b": 2, "a": 1} describe the same object. This page ignores order; a line diff would report it.
How are arrays compared?
When the items carry a unique identity field such as id, they are matched by it, so an inserted or reordered item does not make every later one look changed. Without one, items are matched by their content. You can switch to strict position matching when the order itself is what you are checking.
Can I compare two API responses?
Yes. Paste the two response bodies. Values that change on every call, such as timestamps and request IDs, are labelled noise, and any other path can be ignored with one click, so what remains is the real difference in behaviour.
What if one side is not valid JSON?
The tool says which side does not parse and where, for example the line of a trailing comma, and compares the two as plain text until it does. Fix the error and it offers to compare them as data again.
Is my JSON sent anywhere?
No. Both documents are parsed and compared in your browser. The only thing that can leave the page is an optional AI explanation, and only for the changes you tick, after you have seen exactly what would be sent.