JSON Diff

Compare two JSON objects and visualize differences. Outputs RFC 6902 JSON Patch operations and a color-coded tree diff. Runs in your browser.

  • Runs in your browser
  • Your data never leaves your browser
  • Free · No Sign-Up
Click Compare or press Ctrl+Enter (⌘+Enter on Mac). Both inputs must be valid JSON. Comparison runs only on request; formatting and object key order do not affect the patch. Clear or Ctrl+L (⌘+L on Mac) empties both inputs, results and status while focus is inside the tool. Swap exchanges both inputs and clears the results. Click Compare again to generate the reverse patch.
Enter the original JSON value: an object, array, string, number, boolean or null. Comments and trailing commas are invalid JSON. Numbers use JavaScript precision.
Enter the changed JSON value. Arrays compare by index, not by an id field. Editing either input clears old results without comparing automatically.
Result When differences exist, Hide inputs frees space for the results without discarding text. Show inputs restores the editors. Identical values show a status message without a patch.

Compare two JSON values to see their patch and visual differences here.

Examples, details and FAQ Worked examples, how it compares with other tools, and answers to common questions.

Use Cases

  • Review API response changes between versions.
  • Generate patch operations for PATCH HTTP endpoints.
  • Audit configuration file changes.
  • Debug unexpected data mutations in your application.

Related tool: JSON Formatter — prettify and validate JSON before diffing.

Example: An API Response Changes

Before:

{"name":"Alice","status":"pending","legacy_id":12345,"tags":["a","b","c"],"profile":{"age":30,"city":"Paris"}}

After (keys reordered, status changed, legacy_id removed, role added, first tag dropped):

{"status":"active","name":"Alice","role":"admin","tags":["b","c"],"profile":{"age":31,"city":"Paris"}}

Visual Diff:

~status: "pending" → "active"
−legacy_id: 12345
~tags.0: "a" → "b"
~tags.1: "b" → "c"
−tags.2: "c"
~profile.age: 30 → 31
+role: "admin"

JSON Patch:

[
  { "op": "replace", "path": "/status", "value": "active" },
  { "op": "remove", "path": "/legacy_id" },
  { "op": "replace", "path": "/tags/0", "value": "b" },
  { "op": "replace", "path": "/tags/1", "value": "c" },
  { "op": "remove", "path": "/tags/2" },
  { "op": "replace", "path": "/profile/age", "value": 31 },
  { "op": "add", "path": "/role", "value": "admin" }
]

Key order does not matter: name moved but is not reported, because a JSON object is an unordered collection of members (RFC 8259, section 4). The operations run from top to bottom, and each one sees the document as the previous one left it (RFC 6902, section 3). The patch applies with Python’s jsonpatch 1.33 and gives the After document:

import jsonpatch  # pip install jsonpatch

before = {"name": "Alice", "status": "pending", "legacy_id": 12345,
          "tags": ["a", "b", "c"], "profile": {"age": 30, "city": "Paris"}}
patch = jsonpatch.JsonPatch([...])  # paste the patch from the tool
after = patch.apply(before)

Example: Several Items Removed From a List

An order that had three line items now has one, and its quantity changed:

[
  { "op": "replace", "path": "/items/0/qty", "value": 3 },
  { "op": "remove", "path": "/items/2" },
  { "op": "remove", "path": "/items/1" }
]

The removals are written from the highest index down. After remove /items/2 the array has two elements, so /items/1 still exists. In the other order, the second removal would point past the end of the array; when an operation fails, the whole patch fails (RFC 6902, section 5).

How Arrays Are Compared

Arrays are compared by index, not by content. Dropping the first tag from ["a","b","c"] shows up as two replacements and one removal instead of a single remove /tags/0. The patch is correct; it is longer than necessary. Elements past the end of the shorter array become remove operations (highest index first) or add operations (lowest index first).

Paths and JSON Pointer Escaping

Patch paths are JSON Pointers (RFC 6901): ~ is written ~0 and / is written ~1. The whole document is the empty path ""; / would point to a member whose name is the empty string. For {"a/b":1,"m~n":2,"list":[1,2,3]} → {"a/b":2,"list":[1,2,3,4],"x":null} the tool gives:

[
  { "op": "replace", "path": "/a~1b", "value": 2 },
  { "op": "remove", "path": "/m~0n" },
  { "op": "add", "path": "/list/3", "value": 4 },
  { "op": "add", "path": "/x", "value": null }
]

When the two roots have different types, such as an object and an array, the patch replaces the whole document:

[
  { "op": "replace", "path": "", "value": [1] }
]

The Visual Diff joins keys with dots (profile.age, list.3) for reading only; use the paths from the JSON Patch in code.

How the Patches Are Checked

The tool’s test suite applies every generated patch to Before and compares the result with After, using a strict RFC 6902 implementation and, when it is installed, Python’s jsonpatch. Besides the examples on this page, it runs 3,000 random document pairs with nested arrays and keys such as constructor, __proto__, "", a/b, and m~n.

Limits

  • No move or copy operations are generated; a renamed key appears as remove plus add.
  • Arrays of objects are not matched by an id field, and an element inserted at the start of an array makes every later element look changed.
  • Numbers are compared after JavaScript parses them, so 1.0 and 1 are equal, and integers above 2^53 lose precision.
  • Both inputs must be valid JSON. The status line names the side that failed, for example Before JSON parse error: Expected double-quoted property name in JSON at position 7.

FAQ

What is RFC 6902 JSON Patch?

RFC 6902 defines a JSON document format for expressing a sequence of operations to apply to a JSON document. Each operation is an object with 'op' (add/remove/replace/move/copy/test), 'path' (JSON Pointer per RFC 6901), and optionally 'value'.

Is my JSON data sent to any server?

No. The comparison is done in your browser using JavaScript. Nothing leaves your machine.

Can I compare large JSON files?

Yes, but very large objects (thousands of keys or deeply nested arrays) may take a moment to process. All computation is in-browser.

How does the visual diff work?

The tool performs a deep recursive comparison. Keys present only in 'After' are shown as additions (+). Keys present only in 'Before' are shown as removals (−). Keys with changed values are shown as changes (~) with both the old and new values.

How is this different from the Diff Checker tool?

The Diff Checker tool compares plain text line-by-line. This JSON Diff tool understands JSON structure — it compares values semantically, not textually, and outputs machine-readable JSON Patch operations.