100% local

JSON Diff & Compare

data_object Left (Original)
data_object Right (Modified)

JSON Diff & Compare

Compare two JSON documents structurally instead of as text. Each difference is reported with the exact path where it occurs, so you can see what changed without reading both files.

A text diff on JSON is noisy because it reacts to formatting, indentation, and key order, none of which are part of the data. This tool parses both sides first and then walks the two values together, so it reports differences in the structure rather than in the characters. Reformatting a file produces no output at all.

Every difference is reported as a path plus a marker: a plus for a key or index present only on the right, a minus for one present only on the left, and a tilde for a path that exists on both sides with different values. Paths use dots for object keys and square brackets for array indices, so you can paste one straight into your code to reach the value it names.

Arrays are matched by position, and that matters

Objects are matched by key, which is the obvious and correct behaviour. Arrays are matched by index, which is the simple behaviour but not always the one you want. Index matching means element zero is compared to element zero regardless of content, so it reports what changed at each position rather than which items were added or removed.

The consequence shows up when a list is reordered. Take a three element array and move the first item to the end. Nothing was added or removed, but every position now holds a different value, so the diff reports three changes. Insert one item at the front of a ten element array and you get ten reports: nine changed positions and one addition at the tail. The output is accurate about positions, and misleading if you read it as a report about items.

When you care about identity rather than position, sort both arrays by a stable key before comparing, or compare the collections keyed by id instead of as arrays. The JSON Key Sorter handles object keys but deliberately leaves array order alone, so array normalization is something you have to do at the data level. For arrays whose order genuinely is the data, such as a ranking or a sequence of events, index matching is exactly right.

Reading the output

Three markers and a path syntax. Nothing else appears in the result panel.

OutputMeaningNotes
+ path: valueaddedThe path exists only on the right. The value shown is the new one.
- path: valueremovedThe path exists only on the left. The value shown is the one that disappeared.
~ path:changedThe path exists on both sides with different values. Old is listed first, then new.
user.address.cityobject keyObject keys are joined with dots, at any depth.
items[2].idarray indexArray elements are addressed by index in square brackets.
(root)whole documentUsed when the two top level values differ in type, such as an object against an array.

Comparing two versions of a record

One value changed, one key was removed, and one key was added.

Input
left:  {"name":"Ada","age":30,"role":"dev"}
right: {"name":"Ada","age":31,"meta":{"city":"Seoul"}}
Output
~ age:
    - 30
    + 31
- role: "dev"
+ meta: {"city":"Seoul"}

The paths are complete, so name and meta.city can be read directly as accessors. Note that no output is produced for keys that are identical on both sides.

Common Pitfalls

Reordering a list looks like a rewrite

Because arrays are matched by index, moving one element reports a change at every position it shifted. A three item list with the head moved to the tail produces three change entries even though the set of items is identical. Sort both sides by a stable field first if you want to compare membership rather than order.

left:  ["a","b","c"]
right: ["b","c","a"]

~ [0]:  - "a"  + "b"
~ [1]:  - "b"  + "c"
~ [2]:  - "c"  + "a"

A type change is reported as a single change, not a removal plus an addition

If a path holds the number 1 on the left and the string "1" on the right, or an object on one side and an array on the other, you get one tilde entry showing both values. The comparison does not descend into mismatched types, so you will not see a breakdown of what was inside the object that got replaced.

Identical values short circuit, including identical nulls

Comparison stops as soon as two values are strictly equal, so a key present on both sides with the value null produces no output. If you are hunting for fields that are null when they should be populated, a diff against another document will not surface them. Use the viewer to inspect a single document for that.

How to Use

  1. Paste original JSON: Put the version you are treating as the baseline on the left, such as the current production response.
  2. Paste modified JSON: Paste the modified JSON document into the right panel.
  3. Click Compare: The tool compares both documents recursively and shows all differences with their JSON paths.

Key Features

  • Deep recursive comparison of nested objects and arrays
  • Path-based output showing exact location of each difference
  • Three change types: added (+), removed (-), and changed (~)
  • Load JSON from files for easy comparison of large documents

Use Cases

  • Comparing API responses before and after a code change
  • Reviewing configuration file changes between environments (dev, staging, production)
  • Validating data migration results by comparing source and target records

Frequently Asked Questions

How are differences displayed?

Each difference shows the JSON path, type of change (added, removed, or changed), and the old/new values.

Does it compare nested objects?

Yes. The comparison is recursive and detects differences at every nesting level, including arrays.

How are array differences detected?

By index. Element zero is compared with element zero, and so on. Elements beyond the length of the shorter array are reported as added or removed at their index. Moved elements are not detected as moves.

What if both JSONs are identical?

If no differences are found, the result will display 'No differences found.' confirming that both documents are identical.

Can I compare very large JSON files?

Yes, but performance depends on your browser. For very large files (over 10 MB), the comparison may take a few seconds. All processing happens locally.

Why does reordering an array produce so many differences?

Arrays are compared position by position, so shifting one element changes the value at every position after it. Each of those positions is reported. Sort both arrays by a stable key before comparing if you care about membership rather than order.

Does formatting or key order affect the result?

No. Both sides are parsed before comparison, so indentation, whitespace, and the order of object keys are invisible to the diff. Only the parsed values are compared.