Quick answer
A JSON diff recursively walks two documents and reports every key that was added, removed, or changed, showing the dotted path to each difference. Both sides are parsed first, so key order and whitespace are ignored — only real structural and value differences show up. It runs entirely in your browser; nothing is uploaded. Paste JSON into A and B, then click Compare.
How JSON Diff Works
The tool recursively compares every key and value in both JSON objects:
- + Added (green) — key exists in B but not in A
- − Removed (red) — key exists in A but not in B
- ~ Changed (yellow) — key exists in both but the value differs
- ⇅ Moved (blue) — the same array element appears at a different position, with its contents unchanged
Nested paths are shown in dot notation (e.g., user.address.city) so you can pinpoint exactly where the difference is. Array elements matched by identity show as [id=42].status rather than a bare index, so the path still means something after a reorder.
Click any summary badge to filter the table down to that change type — useful when a large diff has a handful of real changes buried among many additions.
Need to format your JSON first? Use the JSON Formatter. Need to validate? Try the JSON Validator.
When to Use JSON Diff
- Comparing two versions of an API response to see exactly what a backend change affected.
- Auditing configuration differences between environments — spot what changed from
devtoprodbefore a deployment. - Reviewing JSON data migrations or pipeline transformations to confirm no fields were dropped or altered unexpectedly.
- Confirming a refactor did not accidentally change a response contract before merging a pull request.
Worked example
Comparing two versions of the same record — one field edited, one removed, one added:
JSON A (original)
{
"name": "Alice",
"age": 30,
"city": "New York"
}
JSON B (modified)
{
"name": "Alice",
"age": 31,
"country": "USA"
}
Diff result
~ age 30 → 31 (changed)
- city "New York" (removed)
+ country "USA" (added)
What happened
nameis identical in both, so it isn't reported.ageexists in both but the value differs — a changed row showing old and new.cityis in A but not B — removed.countryis in B but not A — added.
Edge cases & gotchas
- Array comparison is by index, not by value. Element 0 in A is compared to element 0 in B, so reordering a list — even with identical contents — reports many changes. There's no order-insensitive array matching.
- Type changes count as changed.
"30"(string) versus30(number) is a difference, which is useful for catching an API that started returning numbers as strings. - Key order and whitespace are ignored. Both sides are parsed first, so
{"a":1,"b":2}and{"b":2,"a":1}show no differences — the diff is structural, not textual. - Nested differences use dotted paths. A change deep in the tree is reported as
user.address.cityso you can jump straight to it. - Duplicate keys resolve before diffing. Because each side is parsed, a repeated key keeps only its last value, so the diff compares the resolved objects.
Frequently Asked Questions
How does the JSON diff work?
The tool recursively walks both JSON objects and compares every key and value. Added keys are highlighted in green, removed keys in red, and changed values in yellow.
Is my JSON data sent to a server?
No. All comparison happens entirely in your browser using JavaScript. Your data never leaves your device.
Does it handle nested JSON objects?
Yes. The diff is recursive — nested objects and arrays are compared at every level, and the path to each difference is shown (e.g., user.address.city).
What do the colors mean?
Green (+) means a key exists in B but not in A (added). Red (−) means a key exists in A but not in B (removed). Yellow (~) means the key exists in both but the value is different (changed).
Does JSON Diff handle arrays with reordered elements?
Yes. By default arrays of objects are matched by an identity key — id, _id, uuid, key, name, slug or code — chosen automatically when that property is present and unique on every element. Elements are then compared to their true counterpart rather than to whatever sits at the same index, so a reordered list reports "moved" instead of flagging every field as changed. You can name the key explicitly, or switch to position matching if index order is what you actually care about. Arrays of primitives are always compared positionally.
How do I ignore timestamps and other noisy fields?
Enter path patterns in the "Ignore paths" box, separated by commas. A pattern such as *.updatedAt excludes that field at any depth, and meta.requestId excludes one specific path. This is the usual way to compare two API responses where timestamps, request IDs and generated tokens would otherwise bury the differences that matter.
Can I export the differences as a JSON Patch?
Yes. Click "Generate JSON Patch" to produce a standard RFC 6902 patch — an array of add, remove and replace operations with JSON Pointer paths — that transforms document A into document B. It works with fast-json-patch in JavaScript, the jsonpatch library in Python, and any other RFC 6902 compliant client.
Can I ignore small floating point differences?
Yes. Set a number tolerance and any two numbers within that absolute distance of each other are treated as equal. This is useful when comparing computed values, currency rounding or results from different floating point implementations, where 1.0000001 and 1.0 are not meaningfully different.
Can I compare JSON with different key ordering?
Yes. Both inputs are parsed before comparison so key order in objects does not matter. {"a":1,"b":2} and {"b":2,"a":1} show no differences.
When should I use JSON Diff?
Use JSON Diff when comparing two versions of an API response to see what changed, auditing configuration differences between environments (dev vs. prod), reviewing JSON data migrations, or confirming a refactor did not accidentally change a response contract.