JSON Patch Generator

Diff two JSON documents into an RFC 6902 JSON Patch, or apply an existing patch to a target document.

Stop hand-writing PATCH bodies or diffing JSON documents by eye. Paste an original and an updated document to get a standards-compliant RFC 6902 patch back, or paste a target document and a patch to see exactly what applying it produces — both directions run entirely in your browser.

  • Generates add, remove and replace operations from a real diff
  • Applies all six RFC 6902 operations, including move, copy and test
  • Correct JSON Pointer escaping for ~ and / in key names
  • Catches a failed test assertion instead of silently applying a stale patch
  • No account, no upload — everything runs client-side

What is a JSON Patch?

A JSON Patch (RFC 6902) is a JSON document describing a sequence of operations to apply to another JSON document — instead of sending a whole updated document over the wire, you send just the changes. It's the format behind PATCH requests in many REST APIs, Kubernetes' strategic merge patches, and config-management diffing tools.

Each operation is one of six kinds — add, remove, replace, move, copy, test — targeting a location with a JSON Pointer path like /user/tags/0.

JSON Patch vs. JSON Merge Patch vs. a Diff View

JSON Patch (RFC 6902)JSON Merge Patch (RFC 7396)JSONKit's JSON Diff
FormatArray of operationsA partial document to mergeA visual, human-readable comparison
Can remove a keyYes — explicit remove opYes — set value to nullN/A (view only)
Can reorder / move valuesYes — move opNoN/A
Machine-applicableYes — apply directlyYes — shallow mergeNo — for reading, not applying
Best forPrecise API PATCH bodiesSimple partial updatesReviewing what changed

Example

Given this change:

json
// Original
{ "name": "Ravi", "role": "editor", "tags": ["beta"] }

// Updated
{ "name": "Ravi Kumar", "role": "admin", "tags": ["beta", "verified"] }

The generated patch:

json
[
  { "op": "replace", "path": "/name", "value": "Ravi Kumar" },
  { "op": "replace", "path": "/role", "value": "admin" },
  { "op": "add", "path": "/tags/1", "value": "verified" }
]

Applying a Patch in Your Backend

javascript
// npm install fast-json-patch
import { applyPatch } from "fast-json-patch";

const target = { name: "Ravi", role: "editor", tags: ["beta"] };
const patch = [
  { op: "replace", path: "/name", value: "Ravi Kumar" },
  { op: "replace", path: "/role", value: "admin" },
  { op: "add", path: "/tags/1", value: "verified" },
];

const result = applyPatch(target, patch).newDocument;
console.log(result);
// { name: "Ravi Kumar", role: "admin", tags: ["beta", "verified"] }
python
# pip install jsonpatch
import jsonpatch

target = {"name": "Ravi", "role": "editor", "tags": ["beta"]}
patch = jsonpatch.JsonPatch([
    {"op": "replace", "path": "/name", "value": "Ravi Kumar"},
    {"op": "replace", "path": "/role", "value": "admin"},
    {"op": "add", "path": "/tags/1", "value": "verified"},
])
result = patch.apply(target)
print(result)

Move, Copy and Test — the Other Three Operations

The generator only ever emits add, remove and replace — enough to describe any change unambiguously. But a hand-written or third-party patch can use all six operations, and the Apply Patch mode above supports every one of them:

json
[
  { "op": "test", "path": "/version", "value": 3 },
  { "op": "move", "from": "/draftTitle", "path": "/title" },
  { "op": "copy", "from": "/author", "path": "/lastEditedBy" }
]

move relocates a value from one path to another in a single atomic step (equivalent to a remove then an add, but expressed as one intent). copy duplicates a value to a new path without removing the original. test doesn't modify anything — it asserts that the value at a path equals a given value, and aborts the entire patch if it doesn't match, which is the standard way to express optimistic concurrency control ("only apply this if nothing else changed /versionsince I read it") directly inside the patch document itself, with no separate ETag or version-check request needed.

Where JSON Patch Shows Up in Practice

  • REST API PATCH endpointsSend only the fields that changed, with Content-Type: application/json-patch+json, instead of a full PUT replacement
  • Kubernetes strategic merge and JSON patcheskubectl patch and the Kubernetes API both accept RFC 6902-style patches for precise, partial resource updates
  • Optimistic concurrency controlA leading test operation aborts the whole patch if the resource changed since you last read it, avoiding a lost-update race
  • Config drift and change auditingStore a patch alongside a change request as a precise, reviewable record of exactly what changed and where

Frequently Asked Questions

Arrays are compared index by index — an element that changed at index i becomes a replace at that index, extra trailing elements in the updated array become add operations, and extra trailing elements in the original become remove operations. It does not do a full sequence-alignment (LCS) diff, so an element inserted in the middle of an array will show up as a run of replace operations rather than a single insert — the applied result is still correct, just not the minimal possible patch.

No — the generator only emits add, remove and replace, which is enough to describe any change and is what most JSON Patch libraries (like fast-json-patch's compare()) produce by default too. The Apply Patch mode, however, supports all six RFC 6902 operations — including move, copy and test — for patches you've written or received elsewhere.

It asserts that the value at a path equals a given value, and aborts the whole patch if it doesn't match. It's typically used as an optimistic-concurrency guard — e.g. "only apply this patch if /version is still 3".

Per RFC 6901, a ~ in a key is escaped as ~0 and a / is escaped as ~1 inside the JSON Pointer path, so a key literally named "a/b" produces the path segment /a~1b. This is handled automatically in both directions.

No — generating and applying patches both run entirely in your browser using JavaScript. Nothing is uploaded to a server.

application/json-patch+json — a distinct media type from plain application/json, specifically so a server can tell a PATCH request apart from a full-document PUT/POST body and route it to the correct handler.

The whole patch is rejected — no partial application happens. The tool reports which operation failed and why, the same behavior a spec-compliant server-side JSON Patch library should have when a client sends a patch whose test assertion no longer holds.

Related Tools