Skip to content
JSON Diff Checker
More free tools

JSON diff in Python vs online

You can do a JSON diff in Python with a few lines and no packages. You can also paste both files into an online JSON diff checker. This page shows both ways, so you can pick the one that fits the job.

The short version

Use Python when the check is part of a script or a test. Use an online JSON diff tool when you want to look at the changes once, or when you want to send the result to someone.

Step 1: check if two JSON files are equal

Load both files with json.load. Python then compares the parsed values. Key order and spacing do not matter.

import json, sys

with open(sys.argv[1]) as f1, open(sys.argv[2]) as f2:
    a, b = json.load(f1), json.load(f2)
print("equal" if a == b else "different")

This tells you if the files differ. It does not tell you where.

Step 2: list every change by path

This function walks both values at the same time. It yields the kind of change, the path, the old value and the new value.

import json

def diff(a, b, path="$"):
    """Yield (kind, path, old, new) for every difference between two parsed JSON values."""
    if isinstance(a, dict) and isinstance(b, dict):
        for key in sorted(a.keys() | b.keys()):
            child = f"{path}.{key}"
            if key not in b:
                yield ("removed", child, a[key], None)
            elif key not in a:
                yield ("added", child, None, b[key])
            else:
                yield from diff(a[key], b[key], child)
    elif isinstance(a, list) and isinstance(b, list):
        for i in range(max(len(a), len(b))):
            child = f"{path}[{i}]"
            if i >= len(b):
                yield ("removed", child, a[i], None)
            elif i >= len(a):
                yield ("added", child, None, b[i])
            else:
                yield from diff(a[i], b[i], child)
    elif a != b or type(a) is not type(b):
        yield ("changed", path, a, b)

old = json.loads('{"name": "Ada", "age": 36, "tags": ["a", "b"], "city": "London"}')
new = json.loads('{"age": 37, "name": "Ada", "tags": ["a", "c", "d"], "email": "ada@example.com"}')
for kind, path, before, after in diff(old, new):
    print(kind, path, json.dumps(before), json.dumps(after))

The output for the example:

changed $.age 36 37
removed $.city "London" null
added $.email null "ada@example.com"
changed $.tags[1] "b" "c"
added $.tags[2] null "d"

The type(a) is not type(b) check matters. In Python, 1 == True is True, so without it a number that became a boolean would be reported as equal.

Step 3: get a line diff with difflib

If you only want a text view, format both documents the same way and compare the lines. Sorting the keys removes false changes from key order.

import difflib, json

a = json.dumps({"a": 1, "b": [1, 2]}, indent=2, sort_keys=True).splitlines()
b = json.dumps({"a": 2, "b": [1, 2, 3]}, indent=2, sort_keys=True).splitlines()
print("\n".join(difflib.unified_diff(a, b, "old.json", "new.json", lineterm="")))

The result is a unified diff, the same format Git uses:

--- old.json
+++ new.json
@@ -1,7 +1,8 @@
 {
-  "a": 1,
+  "a": 2,
   "b": [
     1,
-    2
+    2,
+    3
   ]
 }

Where the Python code falls short

  • Array order. The function above compares items by position. If the same items come in another order, it reports many changes.
  • Matching by id. To pair array items by a key such as id, you must write that code yourself.
  • Ignored fields. Fields such as updatedAt need an extra filter step.
  • Big numbers. Python keeps big integers exact. A float such as 1.0 equals 1, which may or may not be what you want.
  • Reading the result. Printed lines are fine for ten changes. They are hard to read for hundreds.

JSON diff online: when it is faster

For a one-off check, an online JSON diff viewer saves the code. On the JSON diff checker you paste the two documents and read a list of changes with the path, the old value and the new value. It can ignore array order, match array items by id and ignore fields. Everything runs in your browser, and your JSON is not sent to a server.

Python or online?

SituationBetter fit
A check in a test or a build scriptPython
A one-time look at two API responsesOnline
Arrays in a different order, or matched by idOnline, or extra Python code
Sharing the result with a colleagueOnline, with a share link
Files you must not paste into a web pagePython

Ready to try it? Open the online JSON compare tool and press Sample to see every kind of change.

More free tools from Bingemind