Why a text diff is the wrong tool for JSON
A line-by-line diff compares characters. JSON has several ways of writing the same data with different characters, and a text diff reports every one of them as a change:
| Difference in the text | Difference in the data? |
|---|---|
| Indentation, spaces and line breaks | No |
{"a":1,"b":2} against {"b":2,"a":1} | No — object members have no order |
1.0 against 1, or 1e2 against 100 | No — the same number |
"\u00e9" against "é" | No — the same string |
[1,2] against [2,1] | Yes — arrays are ordered |
1 against "1" | Yes — a number is not a string |
null against a missing key | Yes — present-but-empty is not absent |
Serialisers reorder keys freely. Go sorts map keys alphabetically, many languages keep insertion order, and a database round trip can shuffle them again. Compare two responses from different servers as text and you may see every line flagged while the data is identical. This tool parses both sides first and compares the resulting values, so only the last three rows of the table are ever reported.
When you do want a character-level view — to review formatting, or to compare files that are not JSON — the diff checker is the line-by-line tool.
Reading the result
Each difference is one row: a label, the path to the value, and the values involved.
| Label | Meaning | Shown |
|---|---|---|
| CHANGED | The path exists on both sides with different values | Old value → new value |
| ADDED | The path exists only on the right | The new value |
| REMOVED | The path exists only on the left | The old value |
Paths use the same notation as the JSON viewer:
$.customer.email, $.items[2].sku. When the type of a value changes,
the row says so — (number → string) — because that is the change most likely to break a
client that was working yesterday. When an entire object or array is added or removed it is reported
once, at its own path, and not as a separate row for everything inside it.
Copy report gives the same list as plain text, with +, - and
~ prefixes, for pasting into a ticket or a pull request.
Arrays: by position, or ignoring order
In JSON an array is an ordered list, so by default item 0 on the left is compared with item 0 on the right. That is correct for anything where position means something: steps, coordinates, ranked results. It has one unhelpful effect. Insert a single item at the front and every later item is compared with its neighbour, so the report shows a long run of changes instead of one addition.
Many arrays are really sets: tags, permissions, IDs, rows returned without an ORDER BY.
For those, switch to Arrays: ignore order. Items are then matched by their whole value,
wherever they sit, and only items with no match on the other side are reported, as an addition or a
removal at path[]. An item that was edited appears as one removal and one addition, since
with order ignored there is no position to say which old item it corresponds to.
What people use it for
- Comparing environments. The same request against staging and production, pasted side by side. The API tester gets you both bodies.
- Checking a refactor. Capture a response before the change and after it. An empty report is the proof that behaviour is unchanged.
- Reviewing an API version. Diff a
v1response againstv2to list the renamed, removed and retyped fields a client will need to handle. - Debugging a webhook. Compare the payload you received with the provider's documented example, or with the webhook examples on this site, to spot a field that moved.
- Config drift. Two JSON configuration files that should be the same and are not. For YAML, convert both with YAML to JSON first.
Fields that always differ, such as timestamps and request IDs, will always be reported. Read past them, or remove them from both sides before comparing. If either side fails to parse, the JSON validator will show where.
Frequently asked questions
How do I compare two JSON files online?
Paste the first into the left box and the second into the right, then press Compare. The tool parses both and lists every path whose value was changed, added or removed.
Does the order of keys matter when comparing JSON?
No. The members of a JSON object are unordered, so two objects with the same names and values are equal however they are written. This tool never reports key order as a difference.
Does the order of items in an array matter?
Yes, by the JSON specification: arrays are ordered lists. For arrays that are really sets, such as tags, choose the option to ignore array order and items are matched by value instead of by position.
What is the difference between a JSON diff and a text diff?
A text diff compares lines of characters, so reformatting or reordering keys shows up as changes. A JSON diff compares the parsed data, so only real differences in values, types and structure are reported.
Are 1 and 1.0 treated as different?
No. Both are the same JSON number, and they compare as equal. A number and a string, such as 1 and "1", are different types and are reported as a change.
Is null the same as a missing key?
No. A key present with the value null is reported as different from a key that is absent, because many APIs treat the two differently, for example when a PATCH request uses null to clear a field.
Is my data uploaded?
No. Both documents are parsed and compared in JavaScript on this page, and no network request is made with them.
Related tools and reference
Diff Checker
Line-by-line comparison for any text, formatting included.
JSON Viewer
Open either document as a tree and follow a reported path.
JSON Validator
Find the syntax error when one side will not parse.
JSON Formatter
Pretty-print a document before reading it.
Case Converter
Bring two payloads to the same key convention before comparing them.
API Tester
Fetch the two responses you want to compare.
REST API Testing
Where response comparison fits in testing an API.