Skip to content

JSON Diff: Compare Two JSON Documents, Ignoring Key Order

Paste an original and a changed JSON document to see which paths were added, removed or changed, with both values side by side. Nothing is uploaded.

Runs in your browserFree, no sign-upLast reviewed

Settings

Key order and whitespace are ignored. Arrays are compared position by position.

Results update automatically as you type.

8 differences. 3 added, 1 removed, 4 changed. 3 values are the same on both sides.

Summary

Differences
8
Added
3
only in Changed
Removed
1
only in Original
Changed
4
different value or type
Unchanged values
3
Values compared
8 vs 10

Differences by path

ChangePathOriginal valueChanged value
Changedversion"1.4.0""1.5.0"
Removedprivatetrue
Changedscripts.dev"next dev""next dev --turbo"
Addedscripts.lint"eslint ."
Changedtags[1]"browser""offline"
Addedtags[2]"browser"
Changedengines.node">=18"">=20"
Addedlicense"MIT"

Text summary (+ added, - removed, ~ changed)

~ version: "1.4.0" → "1.5.0"
- private: true
~ scripts.dev: "next dev" → "next dev --turbo"
+ scripts.lint: "eslint ."
~ tags[1]: "browser" → "offline"
+ tags[2]: "browser"
~ engines.node: ">=18" → ">=20"
+ license: "MIT"

Quick answers

How do I compare two JSON files online?
Open each file, paste one into Original JSON and the other into Changed JSON. The tool lists every path that was added, removed or changed, with the old and new value for each. The comparison runs in your browser, so the files are not uploaded.
Does key order matter when comparing JSON?
Not here, and not in the JSON specification, which defines an object as an unordered set of name and value pairs. {"a":1,"b":2} and {"b":2,"a":1} are reported as having no differences. Array order does matter and is compared.
What is a semantic JSON diff?
A comparison of the parsed data instead of the characters. It ignores indentation, line breaks, key order and equivalent spellings such as 1.0 and 1, and reports only real changes: a key added or removed, or a value or type that differs.
Why does a text diff show changes when the JSON is the same?
A text diff compares lines. Reformatting, minifying or serialising keys in a different order changes almost every line without changing the data. Parsing both sides first removes that noise.
Is null the same as a missing key?
No. If the original has "a": null and the changed document has no key a, the path a is listed as Removed with the value null. A key that exists with null on one side and 0 on the other is listed as Changed (null to number).
Is 1 equal to "1" in a JSON comparison?
No. One is a number and the other is a string. The row is marked Changed (number to string) so that type changes, a common cause of API bugs, stand out from ordinary value changes.

What JSON Diff does

This tool parses both documents and compares the data, not the text. Two objects with the same keys in a different order are equal, and so are a minified file and a pretty-printed copy of it. What you get back is a table with one row per difference: the path (for example scripts.dev or tags[1]), whether it was added, removed or changed, and the original and changed values. Counts for each kind sit above the table, with the number of values that are the same on both sides. Arrays are compared position by position, because order in a JSON array carries meaning. If either side fails to parse, the error says which box it is and where the problem is.

Worked examples: what each kind of change looks like

Each result below is the real output of the tool for the input shown.

Same data, different key order

Original: {"a":1,"b":{"c":2,"d":3}} Changed: {"b":{"d":3,"c":2},"a":1.0}

No differences. 3 unchanged values.

The keys are reordered at two levels and 1 is written as 1.0. None of that changes the data.

A value changed and a key added inside a nested object

Original: {"scripts":{"dev":"next dev","build":"next build"}} Changed: {"scripts":{"build":"next build","dev":"next dev --turbo","lint":"eslint ."}}

Changed scripts.dev: "next dev" to "next dev --turbo". Added scripts.lint: "eslint .". 1 unchanged value.

A type change

Original: {"id":1,"v":null,"o":{}} Changed: {"id":"1","v":0,"o":[]}

3 changed: id (number to string), v (null to number), o (object to array).

An item inserted at the start of an array

Original: ["a","b","c"] Changed: ["x","a","b","c"]

Changed [0], [1] and [2]; Added [3]: "c". 4 differences.

Arrays are matched by position, so an insertion shifts every later item. See the section on arrays below.

Nested arrays of objects, JSON Pointer paths

Original: {"users":[{"id":1,"roles":["a","b"]},{"id":2}]} Changed: {"users":[{"id":1,"roles":["a"]},{"id":3,"x":true}]}

Removed /users/0/roles/1: "b". Changed /users/1/id: 2 to 3. Added /users/1/x: true.

What counts as a difference and what is ignored

SituationReported asWhy
Keys in a different orderNo differenceJSON objects are unordered
Different indentation, line breaks or minificationNo differenceWhitespace between tokens is not data
1 and 1.0, or 1e2 and 100No differenceBoth parse to the same number
"caf\u00e9" and "café"No differenceAn escape and the character it stands for are the same string
Key present only in Changed JSONAddedThe path is new
Key present only in Original JSONRemovedThe path is gone
Same path, different valueChangedBoth values are shown
Same path, different type (1 and "1", {} and [])Changed, with both types namedTypes are compared before values
null on one side, key missing on the otherAdded or RemovedA null value is still a present key
Array items in a different orderChanged at each position that differsArray order is significant in JSON
A trailing space inside a stringChangedStrings are compared exactly

How arrays are compared, and when that is not what you want

Item 0 of the original is compared with item 0 of the changed document, item 1 with item 1, and so on. If one array is longer, the extra positions are listed as Added or Removed. This is exact and predictable, and it matches how most code reads an array.

The cost shows up when an item is inserted or deleted near the start. Every later item moves by one position and is reported as Changed, even though it only shifted. The tool does not try to detect moves or match array items by an id field. [1,2,3] against [3,2,1] gives two differences, at [0] and [2].

If the order of a list does not matter in your data, such as a set of tags or permissions, sort the array the same way on both sides before pasting and the comparison becomes order-independent for that list.

Dot notation and JSON Pointer paths compared

The Path style option changes only how each location is written. JSON Pointer is the format from RFC 6901, used by JSON Patch and JSON Schema.

LocationDot notationJSON Pointer
Key dev inside scriptsscripts.dev/scripts/dev
Second item of tagstags[1]/tags/1
Key x of the second userusers[1].x/users/1/x
A key that contains a dot: a.b["a.b"]/a.b
A key that contains a slash: k/z inside "x y"["x y"]["k/z"]/x y/k~1z
A key that contains a tilde: ~t["~t"]/~0t
The whole document(root)(root)

In JSON Pointer a slash inside a key is written ~1 and a tilde is written ~0.

Limits to know before you rely on the result

  • Numbers are held as JavaScript doubles. Integers above 9,007,199,254,740,991 and decimals with more than 17 significant digits are rounded before comparison, so 12345678901234567890 and 12345678901234567891 compare as equal. The tool shows a warning when it sees such a number; quote those values as strings to compare them exactly.
  • If a key appears twice in the same object, the last one wins, as in every standard JSON parser. The earlier value is not compared.
  • Input must be strict JSON. Comments, trailing commas, single quotes and unquoted keys are reported as errors, as are JSON5 and JSONC files.
  • The table shows the first 500 differences. The text summary under it always lists all of them.
  • Values longer than 160 characters are shortened in the table. A changed object or array is shown whole only when its type changed; otherwise the rows point to the individual paths inside it.
  • The page does not put your input into the address bar, so a comparison cannot be shared as a link. Copy the text summary instead.

Using JSON Diff

  1. 1

    Paste the earlier version into Original JSON.

  2. 2

    Paste the later version into Changed JSON. The result updates as you type.

  3. 3

    Choose a Path style: dot notation such as user.roles[0], or JSON Pointer such as /user/roles/0.

  4. 4

    Read the Summary for the counts, then the Differences by path table for each path with its original and changed value.

  5. 5

    Copy or download the Text summary if you want to paste the list into a pull request or a ticket.

Answers to common questions

Is my JSON sent to a server?
No. Both documents are parsed and compared by JavaScript in your browser tab. There is no upload and nothing is stored, which matters when the files are API responses or configuration that contain keys or personal data.
What happens if one side is not valid JSON?
The comparison stops and the message names the side and the position, for example: Original JSON is not valid: Expected double-quoted property name in JSON at position 7 (line 1 column 8). That particular message is what a trailing comma produces. If both sides are invalid, both errors are shown. The wording of the reason comes from your browser, so it differs slightly between Chrome, Firefox and Safari.
How is this different from the text diff checker?
The text diff checker compares lines and is the right choice for prose, code and logs. This tool understands JSON structure, so it ignores formatting and key order and tells you the path of each change. Use this one for API responses, package.json, configuration and fixtures.
Can I compare JSON with arrays in a different order?
You can, and each position that differs is reported as changed. There is no ignore-array-order switch, because reordering an array can be a real change. If order is irrelevant for a particular list, sort it on both sides first.
What do the +, - and ~ signs in the text summary mean?
A plus sign marks a path that exists only in the changed document, a minus sign a path that exists only in the original, and a tilde a path whose value differs, written as old value, arrow, new value. The summary is plain text so it pastes cleanly into a code review comment.
What does Unchanged values count?
The number of strings, numbers, booleans, nulls and empty objects or arrays that are equal at the same path on both sides. Values compared shows the same count for each whole document, so 8 vs 10 means the original holds 8 such values and the changed version holds 10.
Can it compare two API responses?
Yes. Paste the response body from each call. Because key order is ignored, differences in how two servers or two versions serialise the same object do not show up, only the fields whose presence, value or type differs.
How large can the documents be?
There is no fixed size limit in the tool. The practical limit is your browser's memory and patience: the result recalculates on each edit, so paste big documents in one go instead of typing into them.

Looking for something else? Browse all developer tools or see every tool.