About this tool
A plain text diff is a poor way to compare JSON. Re-indent a file, or let a serializer write its keys in a different order, and a line-by-line diff lights up everywhere even though the data is identical. This tool parses both documents first and compares the actual values, so formatting and key order are ignored and only real changes are reported — each one with the exact path to the value that changed. Both documents stay in your browser.
How to use JSON Diff
- Paste the original JSON on the left and the changed version on the right. Each side can be an object, an array, or even a single value.
- Click Compare JSON. If either side isn't valid JSON, you'll see the parser's error and, where the browser reports it, the line and column.
- Read the list of differences. Lines starting with
+were added,−were removed, and~changed value or type. - Swap sides to see the same changes the other way round, or copy the list into a code review or ticket.
How the comparison works
- Objects are compared key by key. A key present only on the right is an addition; a key present only on the left is a removal; a key on both sides is compared recursively. Key order never matters.
- Arrays are compared position by position, because order is meaningful in a JSON array. If an item is inserted at the start of a list, every item after it shifts, so you will see changes at each index — that is an accurate description of what changed position.
- Values are compared after parsing, so
1and1.0are equal, while1and"1"are reported as a type change from number to string. - Paths use the common
$.key[index]notation. Keys that aren't simple identifiers are quoted, for example$["first name"].
Worked example
Compare this original:
{"name": "Ada", "age": 36, "roles": ["admin"], "active": true}
with this changed version, which has its keys in a different order:
{"active": true, "age": "36", "name": "Ada L.", "roles": ["admin", "editor"], "team": "core"}
The tool reports four differences: ~ $.name changed from "Ada" to "Ada L."; ~ $.age changed type from number 36 to string "36"; + $.roles[1] added "editor"; and + $.team added "core". The reordered keys and the unchanged active flag produce no output at all. That age change is exactly the kind of bug a text diff hides — the characters 3 and 6 are the same on both sides, but code that expects a number will break.
Common use cases
- Checking what changed between two API responses, for example before and after a deploy
- Reviewing edits to a configuration file, a translation file or a package manifest
- Confirming that a data migration or serializer change didn't alter any values
- Debugging a test that compares an expected object with the actual result
Things to watch out for
Because arrays are compared by position, reordering a list of records shows up as changes at every index even if the same records are present. If order doesn't matter for your data, sort both arrays the same way before comparing. JSON itself has no comments or trailing commas, so files that use them (such as some editor settings files) need those removed first — the JSON Formatter will point to the exact problem. Very large numbers beyond JavaScript's safe integer range can lose precision when parsed, so two long numeric IDs that differ only in their last digits may compare as equal; store such IDs as strings. For comparing plain text or code rather than data, use the Text Diff Checker.
Frequently asked questions
No. Objects are compared key by key after parsing, so the same keys in a different order are treated as identical and produce no differences.
Arrays are compared position by position, because order is meaningful in JSON arrays. Inserting an item near the start shifts every later item, so those positions are reported as changed.
Yes. A change such as the number 36 becoming the string "36" is reported as a type change, even though the characters look the same.
Each difference is labelled with a path from the root, written $. Object keys follow a dot, array positions appear in square brackets, and unusual keys are quoted, for example $.roles[1] or $["first name"].
No. Both documents are parsed and compared in your browser, and nothing is uploaded.