To compare two JSON files and ignore key order, sort the keys in both files and then diff them: diff <(jq -S . a.json) <(jq -S . b.json). In code, parse both files and compare the resulting objects, because Python's == and Node's assert.deepStrictEqual already treat key order as irrelevant. Arrays are different: their order counts unless you sort them on purpose.
Why key order is not a real difference
Key order is not part of a JSON object's meaning. RFC 8259 defines an object as "an unordered collection of zero or more name/value pairs", so {"a": 1, "b": 2} and {"b": 2, "a": 1} carry the same data.
The trouble is that files are text. A plain string comparison of serialized JSON flags a difference when only key order changed, as this DEV Community guide points out. You see it when one service writes keys alphabetically and another writes them in insertion order: git diff shows dozens of changed lines and none of them matter.
The RFC also warns that parsing libraries differ on whether they expose member order at all, so code that depends on it breaks between them.
Compare JSON and ignore key order with jq
jq is the fastest way to compare JSON files on the command line. Its --sort-keys flag (short form -S) will, per the jq manual, "Output the fields of each object with the keys in sorted order", and it does that at every nesting level.
diff <(jq -S . a.json) <(jq -S . b.json)
No output means the files hold the same data. Any line it prints is a real value change, an added key or a removed key. The <( ) syntax is process substitution, which works in bash and zsh; on other shells, write each sorted file to a temporary path first.
If a file holds a stream of JSON values rather than one document, --slurp (-s) reads the whole stream into one array first. For more jq basics, see our guide to pretty printing JSON with jq.
Compare JSON in Python
Python compares parsed JSON without caring about key order. The Python documentation says dictionaries "compare equal if and only if they have the same (key, value) pairs (regardless of ordering)".
import json
with open("a.json", encoding="utf-8") as fa, open("b.json", encoding="utf-8") as fb:
same = json.load(fa) == json.load(fb)
print("same data" if same else "different")
That gives you yes or no, not where. For a readable diff without jq, normalize both files with the standard library and diff the output. The json command-line interface has a --sort-keys option that sorts dictionaries alphabetically by key.
python -m json.tool --sort-keys a.json > a.sorted.json
python -m json.tool --sort-keys b.json > b.sorted.json
diff a.sorted.json b.sorted.json
Our post on pretty printing JSON in Python covers the other formatting options.
Compare JSON in JavaScript and Node.js tests
Node's assert.deepStrictEqual ignores key order when it compares objects. The Node.js assert documentation lists "Object properties are compared unordered" among its comparison rules.
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
const a = JSON.parse(readFileSync("a.json", "utf8"));
const b = JSON.parse(readFileSync("b.json", "utf8"));
assert.deepStrictEqual(a, b);
Don't use JSON.stringify(a) === JSON.stringify(b) instead. It compares strings, so reordered keys make equal data look different. deepStrictEqual only considers enumerable "own" properties, which is exactly what JSON.parse produces.
Key order vs array order
Sorting keys does not touch arrays, and that is correct most of the time. Python compares lists "by comparing corresponding elements", so ["a", "b"] and ["b", "a"] are different, and jq -S leaves arrays in place.
Array order matters when it carries meaning: steps in a pipeline, ranked results, coordinates. It doesn't matter for set-like lists such as tags, roles or feature flags. For those, sort the arrays too. jq's walk(f) "applies f recursively to every component of the input entity", and sort works on any array:
diff <(jq -S 'walk(if type == "array" then sort else . end)' a.json) \
<(jq -S 'walk(if type == "array" then sort else . end)' b.json)
My take: only sort arrays when you know every array in the file is a set. Applied to a whole API response, this filter will happily call two different orderings of a ranked list "equal", and that is the bug you were trying to catch.
Watch out for duplicate keys
Duplicate keys can make two files compare equal when they aren't. RFC 8259 says names in an object "SHOULD be unique", and when they aren't, behavior is unpredictable; many implementations report the last name/value pair only.
A file containing {"mode": "test", "mode": "live"} may parse to just "live" in your comparison script, while another consumer reads "test". If a diff looks clean but production disagrees, search the raw file for repeated keys. Running both files through a JSON Schema check catches a different class of problem, missing or mistyped fields, before you diff.
Use a visual diff after normalizing
A side-by-side view helps when you need to show a colleague what changed. The catch is that most text diff tools compare lines, so you must normalize first: sorted keys, same indentation.
The diff checker on this site has one real limitation here. It compares line N of one input with line N of the other and doesn't realign inserted or deleted lines, so a single added key shifts every line after it. Paste the output of jq -S . from both files, keep the change small, and it works well.
Which method to use
The right method depends on whether you need a yes/no answer or a list of changes.
| Situation | Method |
|---|---|
| Quick check in a terminal | diff <(jq -S . a.json) <(jq -S . b.json) |
| No jq installed, Python available | python -m json.tool --sort-keys on both, then diff |
| Equality check in a Python test | json.load(a) == json.load(b) |
| Equality check in a Node test | assert.deepStrictEqual(a, b) |
| Tags or other set-like arrays | jq walk with sort, as above |
| Showing someone the change | Normalize, then a side-by-side diff |
Large integers can also fool a comparison in JavaScript, since two different IDs may parse to the same number. Our post on JSON large number precision shows when that happens.
FAQ
Does key order matter in JSON?
No. RFC 8259 defines a JSON object as an unordered collection of name/value pairs, so two objects with the same pairs in a different order hold the same data.
How do I diff two JSON files with jq?
Run diff <(jq -S . a.json) <(jq -S . b.json). The -S flag sorts object keys, so only real value changes show up.
Does Python ignore key order when comparing dictionaries?
Yes. Python dictionaries compare equal when they have the same key/value pairs, regardless of ordering. Lists still compare element by element, in order.
Does sorting keys also sort arrays?
No. jq -S and Python's --sort-keys only reorder object keys. Arrays keep their order, which is correct when the order means something.
Can I use a text diff tool to compare JSON?
Yes, but normalize both files first: sort the keys and use the same indentation. Otherwise a line diff reports reordered keys as changes.