How the comparison works
Both inputs are parsed as JSON and compared structurally, value by value. Each difference is reported with a JSONPath-style location such as $.settings.theme or $.roles[1]. Keys that are not plain identifiers are quoted, for example $["first name"].
| Change | Meaning |
|---|---|
| Added | The key or array element exists only in the changed document. |
| Removed | The key or array element exists only in the original document. |
| Changed | Same type in both documents, different value (e.g. "dark" → "light"). |
| Type changed | The JSON type differs, e.g. the number 42 became the string "42", or null became an object. These often indicate API contract changes. |
Rules worth knowing
- Object key order is ignored.
{"a":1,"b":2}and{"b":2,"a":1}are equal. - By default, arrays are compared by position. Element 0 is compared with element 0, and so on. If an item is inserted at the start of a list, every following position is reported as changed. Use the Arrays option below when order does not matter.
- A missing key is different from
null.{}versus{"a": null}is reported as an added key. - Numbers are compared by value.
1,1.0and1e0are equal, because they parse to the same number. Integers beyond JavaScript's safe range (above 9,007,199,254,740,991) are rounded when parsed, so two different IDs such as9007199254740993and9007199254740992compare as equal. The tool shows a warning when either input contains such a number.
Comparison options
Whether array order matters is a decision about your data, not something the JSON itself can tell you. Pick the mode that matches how the API treats the list.
| Option | What it does |
|---|---|
| Arrays: By position | The default. Use it when order is meaningful, such as sorted results, steps or coordinates. |
| Arrays: Ignore order | Treats each array as an unordered collection. [1, 2, 2] and [2, 1, 2] are equal, but [1, 2] and [1, 2, 2] are not, because duplicates are counted. Only unmatched items are listed, so an item with one changed field appears as one removed and one added item. |
| Arrays: Match by key | Pairs objects that have the same value for a key such as id, wherever they are in the list, then shows the field-level changes inside each pair. Paths use JSONPath filter syntax, for example $.users[?(@.id==7)].email. Items without the key, or with a repeated key value, are compared as in "Ignore order". The number 7 and the string "7" are different keys. |
| Ignore keys | A comma-separated list of key names, such as updatedAt, requestId, that are skipped at every depth. Use it for values that change on every request. Names are matched exactly and are case-sensitive. |
Each option applies to every array in the document, including nested ones.
Typical uses
- Checking what changed in an API response between two releases or environments.
- Reviewing configuration changes (feature flags,
package.json, infrastructure settings). - Debugging snapshot test failures where the text diff is noisy because of formatting.
Copy report produces a plain-text summary (+ added, - removed, ~ changed) suitable for pasting into a pull request or ticket. If one of the inputs is invalid, fix it first; the JSON Formatter shows the exact error location.
Comparing JSON on the command line
# Normalise both files with jq, then use a regular diff
diff <(jq --sort-keys . a.json) <(jq --sort-keys . b.json)