Skip to main content

JSON Diff — Compare Two JSON Objects Online, Free

Paste two JSON documents and see exactly which keys were added, removed, or changed — with the full dot-path to each modification. It compares parsed values, not text, so different whitespace and key order compare equal. Free, no signup, 100% in your browser; safe for API payloads and config files.

Left JSON
Right JSON

Added

2

Removed

1

Changed

3

Unchanged

5

Differences (6)
  • ~ changedemail
    Before: "jordan@example.com"
    After: "jordan.lee@example.com"
  • ~ changedrole
    Before: "admin"
    After: "owner"
  • + addedtags[2]
    Value: "veteran"
  • ~ changedsettings.theme
    Before: "dark"
    After: "system"
  • − removedsettings.language
    Was: "en"
  • + addedsettings.timezone
    Value: "UTC"

Semantic Comparison

Compares JSON VALUES at every depth — ignores key order, whitespace, and minification. {a:1,b:2} equals {b:2,a:1} (which a text diff would mis-flag as different).

Path-Indexed Changes

Each change record carries its full path: user.settings.theme, items[3].price. Spot exactly which leaf changed without scanning the whole document.

Added / Removed / Changed

Three change categories with color coding. Removed keys show their old value, added keys show their new value, changed keys show both side-by-side.

100% Client-Side

JSON payloads often contain auth tokens, customer IDs, or internal data. The diff runs entirely in your browser — never uploaded anywhere.

JSON Diff: compare two JSON objects by key, not by line

A JSON diff compares two JSON documents by parsing both into value trees and walking them in lockstep, reporting each added, removed, and changed key with the full path to it (user.settings.theme, items[2].price). Unlike a text diff, it ignores whitespace and key order, so {a:1,b:2} and {b:2,a:1} compare equal. This one is free, needs no signup, and runs 100% in your browser.

How to compare two JSON files

  1. Paste your first document into the left pane and the second into the right pane (or load the sample to try it).
  2. The diff runs instantly — review the path-indexed list of added, removed, and changed records.
  3. Read the summary counts at a glance, then click into any record to see its before/after values side by side.
  4. Leave "Hide unchanged" on to focus only on real differences, or toggle it off to verify full coverage.
  5. Use Swap to flip left/right, or Export to copy a plain-text patch (+/-/~) for code review.

What is a semantic JSON diff and how does it work?

A semantic diff compares the data, not the text. Both inputs pass through native JSON.parse, then a recursive walk compares values at every depth: objects merge their keys into a union set and check each one, arrays compare element-by-element by index, and scalars compare by strict value. Whitespace, indentation, and key order vanish in parsing, so they never reach the comparison.

That key-order independence is not a shortcut — it is the spec. RFC 8259 (and the identical ECMA-404) defines a JSON object as "an unordered collection of zero or more name/value pairs."

"JSON parsing libraries have been observed to differ as to whether or not they make the ordering of object members visible… applications should not rely on member ordering."— RFC 8259, §4 (Objects)

Because the standard says order carries no meaning, a tool that reports reordered keys as "changed" is reporting noise. This diff treats {"a":1,"b":2} and {"b":2,"a":1} as identical — the correct answer per spec.

Worked examples: input → diff

Changed scalar

Left {"role":"admin"} vs Right {"role":"owner"}~ role: "admin" → "owner"

Added & removed key

Left has settings.language, Right has settings.timezone- settings.language and + settings.timezone

Reorder only (no real change)

Left {"a":1,"b":2} vs Right {"b":2,"a":1}0 changes (one unchanged record at root)

Edge case · bigint precision

JSON.parse('9007199254740993') returns 9007199254740992 — one less than the input. Any integer above 253−1 (9,007,199,254,740,991) silently loses precision because JavaScript stores it as an IEEE 754 double. Two IDs that differ only in their final digits can therefore diff as unchanged. For 64-bit IDs, compare them as JSON strings, not numbers.

Six Real-World Uses for JSON Diff

ContextWhy JSON Diff Helps
API response debuggingCompare two API responses across versions or environments to see exactly which fields changed.
Config drift detectionDiff staging-vs-production config files (or two regions) to spot the unintended differences before deploy.
Snapshot test reviewWhen a Jest snapshot test fails, paste old vs new JSON to see precisely what shifted.
Schema migration validationAfter running a migration, diff a sample document before and after to verify only the intended fields changed.
GraphQL response comparisonCompare two GraphQL responses with different query selections to validate field-level data.
Webhook payload investigationDiff two webhook payloads (e.g. before/after a status change) to identify the trigger field.

Text Diff vs JSON Diff — Pick the Right Tool

AspectText Diff (Diff Checker)JSON Diff (this tool)
Comparison unitLines (or characters within lines)Keys, values, array indices at any depth
Whitespace impactDifferent whitespace = different lines = noiseIgnored entirely — pretty vs minified compare equal
Key order{a:1,b:2} differs from {b:2,a:1}Same — semantic equality
Path readabilityJust a line numberuser.settings.theme (clear data-model path)
Output formatTwo side-by-side text panes or unified ±Path-indexed list of change records
Best forProse, code, plain text, logsStructured data, API payloads, configs

Four JSON Diff Gotchas Worth Knowing

1. Arrays Compared by Index

Inserting an element at position 0 shifts every subsequent index, showing the entire array as "changed". For move-aware comparison, normalize array order first (sort by ID) or use a streaming LCS-based differ.

2. Strict Type Comparison

1 ≠ "1", true ≠ 1, null ≠ undefined. This is correct API-debugging behavior — if a type changed, you want to know.

3. Floating-Point Equality

0.1 + 0.2 ≠ 0.3 because of IEEE 754 representation. If your data has computed floats, two semantically-identical results may diff. Round to fixed precision before comparing if needed.

4. Date Strings Are Strings

"2026-05-11T14:00:00Z" vs "2026-05-11T14:00:00.000Z" are different strings even though they represent the same instant. Normalize date format before diffing.

The root short-circuit most diff tools never explain

When two parsed trees are deeply equal, this diff does not walk every key. It pushes a single record at path $ with kind: 'unchanged' and returns. So comparing minified JSON against its pretty-printed twin yields exactly one record, not zero and not hundreds — and with "Hide unchanged" on, the panel shows an empty result. Empty is the "they match" signal.

One more detail worth knowing: a missing key and a key set to null are not the same. A removed key produces a removed record (its value renders as ), while a key whose value changed from a number to null produces a changed record. If a field flips type (object → string), the whole subtree collapses to a single changed record — the walk never recurses across a type boundary.

Runs 100% in your browser

Your JSON never leaves your device. Both documents are parsed with native JSON.parse and compared in memory — no fetch, no upload, no analytics event carrying your payload. You can verify this in DevTools → Network. That matters because real API payloads carry auth tokens, customer IDs, and internal data. I tested this diff on identical-but-reordered objects, nested config files, arrays of differing length, type-flip cases, and multi-thousand-key documents — the comparison stays instant and the path index points straight at each leaf that moved.

Last updated: June 2, 2026 · Runs 100% in your browser — no uploads, nothing leaves your device.

Need a different tool?

Browse all 89 free, in-browser tools — or tell us what we should build next.

Browse all tools