How to Compare Two JSON Config Files and Find What Changed
Two versions of a 300-line JSON config, and one of them breaks production. How to diff them in the browser, ignore key order, read only the changed lines, and do the same with jq and git.
Have broken JSON right now? Fix it free in under 1 second — no signup.
Fix My JSON →Version 2.4.1 of your service config went out and something broke. Version 2.4.0 was fine. Both files are about 300 lines of JSON, and the change is somewhere in the middle. Reading them side by side by eye is how changes get missed. A line diff shows exactly the lines that differ — and nothing else.
Step by step
- Open the JSON diff.
- Paste the old version on the left and the new version on the right.
- Tap Compare JSON. The header shows how many lines changed; unchanged runs are folded so only the changes and a few lines of context remain.
- Read each change. In our example, eight lines differ across 307: the version number,
autoscale.max8 → 12,database.pool20 → 40, a replica count, a timeout, a log level and two feature flags. The pool size and the autoscale limit are the usual suspects when a database starts refusing connections. - Tick "Ignore key order" when the files were written by different tools. Two files with the same data but keys in a different order then compare as equal instead of showing every line as changed.
Both files stay in your browser.
The same thing on the command line
git (for files in a repo):git diff v2.4.0 v2.4.1 -- config/prod.json
jq + diff, ignoring key order and formatting:
diff <(jq -S . old.json) <(jq -S . new.json)
jq -S sorts keys, so only real value changes remain.
Python, to list changed paths instead of lines:
def changes(a, b, path="$"):
if type(a) != type(b): yield path, a, b; return
if isinstance(a, dict):
for k in a.keys() | b.keys():
yield from changes(a.get(k), b.get(k), f"{path}.{k}")
elif isinstance(a, list) and len(a) == len(b):
for i, (x, y) in enumerate(zip(a, b)): yield from changes(x, y, f"{path}[{i}]")
elif a != b: yield path, a, b
Limitations
- It is a line diff, not a semantic diff. A value that moves to another line counts as a removal plus an addition. For a list of paths that changed, use the Python function above.
- Key order matters unless you tick "Ignore key order". Array order always matters —
[1, 2]and[2, 1]are different JSON. - Formatting matters. Minified JSON on one side and pretty-printed on the other compares badly; tick "Ignore key order" (it re-formats both sides) or pretty-print both with the JSON formatter first.
- Both sides must be valid JSON for key-order comparison. Broken JSON can still be diffed as text; repair it first with the repair tool for a clean comparison.
Related
Still dealing with broken JSON?
Paste it in and get it fixed in under 1 second — free, no signup, no install. Works with ChatGPT, Claude, n8n, and any AI output.
Fix My JSON Free →Related Articles