X Xerobit

JSON Diff Tool — Compare Two JSON Objects and Find Differences

A JSON diff tool compares two JSON structures semantically, not textually. It finds added, removed, and changed keys regardless of formatting or key order. Here's how it works...

Mian Ali Khalid · · 5 min read
Use the tool
JSON Diff
Compare two JSON objects structurally with field-by-field diff.
Open JSON Diff →

A JSON diff tool compares two JSON structures at the data level, not the text level. It shows which keys were added, removed, or changed — even if the formatting is different or keys are in a different order.

Use the JSON Diff tool to compare two JSON objects side-by-side with semantic comparison.

Text diff vs semantic JSON diff

Text diff compares character-by-character. Two identical JSON objects formatted differently (different indentation, different key order) show as completely changed:

// Text diff sees everything changed:
-{"name":"Alice","age":30}
+{
+  "age": 30,
+  "name": "Alice"
+}

Semantic JSON diff understands JSON structure. The same example shows no meaningful differences — same keys, same values:

// Semantic diff: no differences

Semantic diff is what you want when comparing API responses, config files, or database snapshots. Text diff works for code where exact formatting matters.

What JSON diff shows

Added key

// Original:
{"name": "Alice", "age": 30}

// Modified:
{"name": "Alice", "age": 30, "email": "alice@example.com"}

// Diff result:
+ "email": "alice@example.com"

Removed key

// Original:
{"name": "Alice", "age": 30, "phone": "555-1234"}

// Modified:
{"name": "Alice", "age": 30}

// Diff result:
- "phone": "555-1234"

Changed value

// Original:
{"status": "pending", "count": 5}

// Modified:
{"status": "active", "count": 7}

// Diff result:
~ "status": "pending""active"
~ "count": 57

Nested changes

JSON diff descends into nested objects, showing exactly which deeply-nested key changed:

// Diff result for nested change:
~ user.address.city: "New York""Boston"

Array changes

Arrays are trickier — JSON arrays are ordered. Most diff tools compare arrays positionally:

// Original: [1, 2, 3]
// Modified: [1, 4, 3]
// Result: index 1: 2 → 4

For arrays of objects, the diff typically tries to match objects by a key (like id) if one is present.

When to use JSON diff

Comparing API responses: When debugging an API, compare the response from two different environments (production vs staging) or two versions of the same request.

Config file auditing: Compare production and development configs. JSON diff ignores formatting differences and shows only meaningful changes.

Database snapshot comparison: Dump two database states as JSON and diff them to find what changed between deployments or backups.

Debugging unexpected behavior: “This worked yesterday, what changed?” Diff the current config/state against yesterday’s snapshot.

Contract testing: Verify that an API response matches the expected schema by comparing against a known-good baseline.

JSON diff in code

JavaScript (json-diff)

const jsonDiff = require('json-diff');

const original = { name: "Alice", age: 30, city: "New York" };
const modified = { name: "Alice", age: 31, city: "Boston", email: "alice@example.com" };

const diff = jsonDiff.diff(original, modified);
console.log(JSON.stringify(diff, null, 2));
// {
//   "age": { "__old": 30, "__new": 31 },
//   "city": { "__old": "New York", "__new": "Boston" },
//   "email": ["+", "alice@example.com"]
// }

Python (deepdiff)

from deepdiff import DeepDiff

original = {"name": "Alice", "age": 30, "city": "New York"}
modified = {"name": "Alice", "age": 31, "city": "Boston", "email": "alice@example.com"}

diff = DeepDiff(original, modified)
print(diff)
# {
#   'values_changed': {
#     "root['age']": {'new_value': 31, 'old_value': 30},
#     "root['city']": {'new_value': 'Boston', 'old_value': 'New York'}
#   },
#   'dictionary_item_added': ["root['email']"]
# }

# Pretty output:
for change_type, changes in diff.items():
    print(f"\n{change_type}:")
    for path, change in changes.items():
        print(f"  {path}: {change}")

Command line (jq + diff)

# Sort keys and format, then use text diff:
diff \
  <(jq --sort-keys . original.json) \
  <(jq --sort-keys . modified.json)

This approach normalizes key order before diffing, which catches semantic equivalence that text diff would miss.

JSON diff output formats

Different tools present diffs differently:

RFC 6902 JSON Patch format: Represents changes as a list of operations (add, remove, replace, move, copy, test). Useful for applying diffs programmatically:

[
  {"op": "replace", "path": "/age", "value": 31},
  {"op": "replace", "path": "/city", "value": "Boston"},
  {"op": "add", "path": "/email", "value": "alice@example.com"}
]

Human-readable diff: Side-by-side or unified view with color-coded additions and removals. Better for review.

Delta format: Compact representation of differences. Used by json-diff npm package.

Common JSON diff use cases

API versioning: When releasing API v2, diff the response schema against v1 to identify breaking changes (removed fields, changed types).

Feature flag audits: Diff the current feature flag config against last week’s to see what’s been changed or enabled.

Kubernetes manifest comparison: Diff two Kubernetes YAML (convert to JSON first) to see what kubectl apply will change.

A/B test configuration: Compare the config for the control group vs treatment group in an experiment.


Related posts

Related tool

JSON Diff

Compare two JSON objects structurally with field-by-field diff.

Written by Mian Ali Khalid. Part of the Data & Format pillar.