Skip to main content

JSON Compare - Deep Diff Two Documents by Path

Default {a:1,b:x} versus {a:2,b:x,c:true} reports $.a changed and $.c added. Key order and whitespace do not count.

Left and right JSON

Repair broken drafts on JSON repair before comparing.

Diff

changed $.a
12
added $.c
true

What Is a JSON Compare Tool?

A JSON compare tool - also called a JSON diff, JSON tree diff, or structural JSON comparison - parses two documents and walks objects and arrays instead of lining up characters. Pretty-print, minification, and key order change a file without changing the value. Git on those files is noisy. This page reports paths. The default left document is {"a":1,"b":"x"}. The default right document is {"a":2,"b":"x","c":true}. Path $.a is changed from 1 to 2. Path $.c is added. Path $.b does not appear because both sides are the string x. That is the gold-standard check for this tool, not a screenshot of a unified text diff.

Deep equality after JSON.parse is the right default for API payloads, feature-flag files, and i18n objects. Arrays are compared by index, not as a longest common subsequence. Inserting at the front shifts every later item and looks like many changes. That is honest for JSON Pointer-style paths and disappointing if you expected a git-style line diff of a list of objects. Sort the arrays first on the JSON editor if identity is a field, not a position. Type changes count as changed, not as remove-plus-add: the number 1 versus the string "1" is one changed path. null versus a missing key is removed or added, because JSON object keys are a set after parse.

This is not a merge tool, not a three-way diff, and not JSON Patch output. It will not ignore a path. Delete noisy keys before comparing, or copy both sides into the editor. Schema validation is a different job on the JSON Schema validator. Selecting a subset of nodes is a different job on JSONPath query. Diffing runs in the browser. Both drafts persist in localStorage for up to 30 days on this device - a convenience, not a source-of-truth store for production configuration.

How to Compare Two JSON Documents - Step by Step

The tree walk runs live as you edit either side. Invalid JSON stops the diff until both sides parse.

  1. Paste the left JSON document - Keep or replace the default left object {"a":1,"b":"x"}. Syntax errors are reported before the tree walk starts.
  2. Paste the right JSON document - The default right object is {"a":2,"b":"x","c":true}. Both sides must parse as RFC 8259 JSON.
  3. Read added, removed, and changed paths - Path $.a is changed from 1 to 2. Path $.c is added. Path $.b does not appear because the string x is equal on both sides.
  4. Copy the report or restore the sample - Copy the path list. Clear restores both default documents. Diffing never uploads.

JSON Diff Worked Example - Before and After

Keep the defaults loaded. You should see exactly two path findings: a change at $.a and an add at $.c. If you also see $.b, the values are no longer the same string.

Input - left versus right

Left:
{
  "a": 1,
  "b": "x"
}

Right:
{
  "a": 2,
  "b": "x",
  "c": true
}

Output - path report

changed $.a
1 → 2

added $.c
true

Swap the two documents and the change reverses (2 → 1) while $.c becomes removed. Reorder keys on the right to {"c":true,"b":"x","a":2} and the report stays the same. Minify either side to a single line and the report stays the same. That is the difference between a tree compare and a text diff.

When You Need a JSON Diff - Real-World Use Cases

Reviewing two versions of an API contract before a client ships

OpenAPI examples and captured responses drift. Paste yesterday's fixture on the left and today's capture on the right. Added keys are fields the client might ignore; removed keys are fields the client still reads; changed paths are the ones that break parsing. A text diff of pretty-printed JSON also works, but only after you normalize key order. This page skips that ritual.

Confirming a PATCH actually changed only the intended fields

You send {"displayName":"Ada"} and the server returns the full resource. Diff the GET-before and GET-after documents. If $.updatedAt and $.displayName changed, that is expected. If $.role changed too, the handler has a bug. The path list is the review comment.

Catching silent type changes on identifiers

Backends sometimes emit numeric ids and later switch to strings, or the reverse. A text diff may show quotes; a naive equality check in tests may coerce. This walker reports a single changed path with both previews. That is the moment to freeze the type in a schema on the JSON Schema validator rather than arguing about == in JavaScript.

Comparing pretty versus minified payloads from two environments

Staging pretty-prints. Production minifies. Staging also sorts keys alphabetically. None of that should count as a release delta. Parse both, walk both, and only ship a ticket if a value moved. If parse fails, the environment is not sending JSON - fix that on the JSON validator first.

Checking fixture drift between staging mocks and local mocks

Front-end mocks rot. Paste the MSW handler body against a real staging response. Added fields are usually safe; removed fields are usually not. Copy the path report into the PR so reviewers do not have to re-run the compare.

Reviewing feature-flag JSON without whitespace noise

Flag files are objects of objects. Teams re-indent them constantly. A tree diff answers “did anyone flip checkout.v2?” without a 200-line whitespace hunk. If the file is JSON5 with comments, convert or strip comments before this page will parse it.

Diffing translation / i18n JSON objects

Locale files are nested maps of strings. Comparing en.json to de.json lists missing keys as removed or added depending on which side is left. That is a coverage checklist, not a linguistic review. Untranslated values that still equal the English string show up as unchanged - you still need a human for that case.

Verifying a repair or editor change did not invent extra keys

After JSON repair or a tree edit, paste the original intent (if you still have a valid copy) against the new document. Heuristic repair can join values or drop comments. A path report is faster than staring at two pretty-prints.

Tree Diff vs Text Diff, JSON Patch, Merge, and Sibling Tools

Pick the comparison that matches the question you are actually asking.

NeedJSON compare (this page)Git / text diffJSON PatchJSON SchemaJSONPath query
Ignore key order and whitespaceNoN/AN/AN/A
See added / removed / changed pathsLine hunksOps listNoSelected nodes only
Apply the delta to a third documentNoPatch files✓ RFC 6902NoNo
Array insert without shifting noiseNo - index compareLCS on linesDepends on generatorNoNo
Validate types and required keysNoNoNoNo
Extract one field from a single documentOverkillGrepNoNo

Three-way merge belongs in git. This page is two documents and a path list. If you need to pretty-print before pasting, use the JSON formatter - formatting will not change the diff once both sides parse to the same value.

Common Diff Errors and Honest Limits

The walker is strict about JSON and honest about what it cannot see.

  • Either side fails parse. Comments, trailing commas, and single quotes stop the diff. Repair on JSON repair or keep JSON5 on the JSON5 validator.
  • Duplicate keys vanish. JSON.parse keeps the last duplicate. You cannot diff a key the parser already discarded.
  • IEEE-754 numbers. Two ids that stringify differently but parse to the same double look equal. Keep large ids as strings.
  • Array identity is position. Prepend an item and every later index looks changed. Sort or key the list first if you care about identity.
  • No ignore-path. Delete noisy timestamps in the editor, then compare again.
  • No merge, no JSON Patch file. Apply edits yourself. This is a report, not a patch engine.
  • Undefined and NaN are not JSON. They never appear as first-class values. If you see them, the text is not RFC 8259.
  • Huge trees stall the tab. Tens of megabytes belong on the JSON file processor for stats, or a local CLI for diffing files on disk.

Privacy & Security - 100% Browser-Side Diffing

Both documents are parsed and walked in your browser with deepDiffJson. Nothing is posted to a compare API. That is appropriate for staging fixtures, flag files, and captured responses - still avoid pasting live production tokens into any web origin. Extensions, shared screens, and screenshots can see the textareas.

Left and right drafts auto-save to localStorage under a key unique to this tool for up to 30 days. The data never leaves this device. Click Clear to restore the default $.a / $.c sample. Clearing site data for this origin deletes the saved pair as well.

Frequently Asked Questions

How does JSON compare differ from a text diff?

A text diff cares about whitespace and key order. This tool parses both documents and walks the tree. {"b":1,"a":2} equals {"a":2,"b":1}. A pretty-printed file and a minified file with the same value have no diff.

What does the default sample show for $.a and $.c?

Left {"a":1,"b":"x"} versus right {"a":2,"b":"x","c":true}. Path $.a changed from 1 to 2. Path $.c was added. Path $.b is unchanged and does not appear in the report.

Are array positions treated as paths?

Yes. Arrays are compared by index. [1,2] versus [1,3] reports $[1] changed. Inserting at index 0 shifts later items and will look like many changes. That is structural comparison, not a longest-common-subsequence of array items.

Does JSON compare upload the documents?

No. Diffing runs entirely in the browser. Both drafts stay in localStorage on this device for up to 30 days and are never sent to a server.

Can I ignore a noisy path when diffing?

Not in this version. Copy the documents into the JSON editor, delete the noisy key, then compare again. There is no ignore-path checkbox and no JSON Patch output.

What about NaN, undefined, or comments?

JSON cannot represent NaN or undefined. Comments are not legal RFC 8259. If parse fails, fix syntax on the JSON validator or JSON repair first, then diff the strict documents.

Does key order count as a difference?

No. After JSON.parse, object keys are a set. Reordering keys without changing values produces an empty diff. That is the point of a tree compare versus git on minified files.

How are type changes reported?

A number 1 versus the string "1" is a single changed path, not a remove plus an add. null versus a missing key is removed or added, because object keys are a set after parse.

Can I merge the two documents after a diff?

No. This page lists added, removed, and changed paths. It is not a three-way merge and it does not emit JSON Patch. Apply edits yourself in the JSON editor.

Is this JSON diff tool free?

Yes. There is no registration, no document-size paywall, and no watermark on the path report. Compare as much JSON as your tab can hold in memory.

Related JSON Tools

A path report is one step. These sibling tools cover query, repair, edit, and validation on the same origin:

  • JSON query - select nodes with JSONPath when you need a field list, not a full tree diff.
  • JSON repair - fix unquoted keys and trailing commas so both sides parse.
  • JSON editor - delete noisy keys or sort arrays before you compare.
  • JSON formatter - pretty-print a valid document; formatting alone will not create a tree diff.
  • JSON validator - syntax-only check when the walker should not run yet.
  • JSON Schema validator - contract checks instead of pairwise equality.
  • JSON viewer - browse one document as a tree.
  • JSON file processor - large files in a worker, not a two-textarea diff.