JSON Compare

Free + AI

Compare two JSON documents as data: key order and formatting ignored, array items matched by id, and every change listed by its path. It runs in your browser.

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, sku or name. 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 /updatedAt or /meta/requestId that 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 -S prints each file with the keys of every object sorted, so key order stops counting before diff compares the text. On this page's sample it leaves the three changed values, the added cardVault and the updatedAt timestamp.

  • 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 are false or null, and on this sample it loses betaCheckout.

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 updatedAt timestamp 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-index took under three seconds. macOS's own diff had not finished the same pair after ten minutes, so at that size use git 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.

Nothing you type leaves this page

The comparison runs entirely in your browser: nothing is uploaded to compare and no account is needed. The one exception is opt-in and visible. If you press Explain with AI, only the changes you ticked are sent, with secrets, email addresses and phone numbers masked first, and the page shows you the exact text before it goes. The explanation keeps change numbers and its own wording, not your text.

Credits are a licence to use these tools - not money, not transferable. Full detail in our privacy policy and AI policy.