How-To

How to Generate a JSON Patch

You have two versions of a JSON document and want the RFC 6902 patch that turns one into the other. Here is how that generation works, what to watch out for, and how to do it in the browser, JavaScript and Python.

To generate a JSON Patch, diff the before document against the after document: every added key becomes an add, every removed key a remove, every changed value a replace. Paste both documents into the JSON Patch generator and it emits the operations for you.

A minimal example

Before

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

After

{
  "name": "Alice",
  "age": 31,
  "active": true
}

Generated patch

[
  { "op": "replace", "path": "/age", "value": 31 },
  { "op": "add", "path": "/active", "value": true }
]

One operation per change, each with a JSON Pointer path to the value it touches.

How a generator decides the operations

The algorithm is a recursive walk of the two documents:

  • Objects are compared key by key: a key only in the after document is an add, only in the before is a remove, in both with different values recurses or becomes a replace.
  • Arrays are usually compared index by index, which is why reordering produces noisy patches (see below).
  • Equal subtrees produce nothing - untouched parts of the document never appear in the patch.

The array caveat

Index-by-index comparison means ["a", "b", "c"] reordered to ["c", "a", "b"] diffs as three replace operations, not one move. The patch is correct - applying it yields exactly the after document - but it says more than a human would. If array ordering matters in your API, review generated patches before sending them. More on array semantics in JSON Patch and arrays, and the raw line-level view in the JSON diff tool.

Generating in code

The same diff is one call in the common libraries:

JavaScript (fast-json-patch)

import { compare } from 'fast-json-patch';

const patch = compare(before, after);
// [{ op: 'replace', path: '/age', value: 31 },
//  { op: 'add', path: '/active', value: true }]

Python (jsonpatch)

import jsonpatch

patch = jsonpatch.make_patch(before, after)
# same RFC 6902 operation list

Both are linked from our language guides: JSON Patch in JavaScript and JSON Patch in Python.

Common mistakes

Expecting the smallest possible patch

Generators compare, they do not optimize. A moved array element usually becomes a remove plus an add, or a chain of replaces - correct, but not minimal. RFC 6902 defines what a patch means, not how to produce a small one.

Assuming two libraries emit the same patch

Generation is not standardized. fast-json-patch, Python jsonpatch and other libraries can emit different - equally valid - patches for the same pair of documents.

Confusing a missing key with a null value

"active": null is a value; a missing "active" is not. A diff treats them differently: missing keys produce add or remove, a null produces replace.

Diffing reordered arrays and trusting the result blindly

Most generators compare arrays index by index, so a reorder looks like "every element changed". The patch is valid but noisy - check it before shipping it.

Reference

The operation semantics a generator targets are defined by RFC 6902, section 4. Generation itself is not standardized - each library chooses its own diff strategy.

Generate this patch yourself

Open the generator with the example above preloaded - edit either side and watch the patch change.

Open the generator with this example