All articles

JSON Diff: how structural comparison differs from text comparison

Compare two JSON documents with a plain text diff (the kind used for code), and the result is often misleading: the same data can be written with a different key order, different indentation, or a different amount of whitespace — and a text diff will show a "difference" where the data is actually identical.

Structural comparison

A structural JSON diff parses both documents into a tree of values and compares the actual data: whether a field exists, what value it holds, whether the type matches. Object key order, extra whitespace, or indentation style aren't taken into account — they're not part of the data itself.

What a diff shows

A typical structural comparison highlights three kinds of changes: fields added in the second document, fields removed from the first, and fields that exist in both but hold different values. Arrays are trickier — the tool has to decide whether to compare elements by position or try to match up similar objects.

Why you need this

  • Compare an API response before and after a backend change to see the actual data differences.
  • Verify that a change to a config file didn't touch anything it shouldn't have.
  • Spot a test regression where the expected and actual JSON differ.

Comparing OpenAPI specs between versions

English-language API documentation overwhelmingly ships as OpenAPI/Swagger JSON (or YAML that gets converted to JSON), and comparing spec versions is a routine part of API governance: did a field become optional, did a required property get dropped, did a response schema change type from string to object. Dedicated tools like openapi-diff exist specifically because a plain text diff of a multi-thousand-line spec file is unreadable, while a structural diff can report exactly which endpoints and schemas actually changed.

Comparing arrays: by position or by key

The simplest approach compares array elements index-to-index, but if a new element is inserted in the middle of the array, every following position "shifts" and the diff reports a change at every element after the insertion point, even though only one item actually changed. Smarter tools try to match elements by a unique field (such as id) instead, so they can show the actual insertion or removal rather than a cascade of false changes.

Try the tool