JSON Patch (RFC 6902)

Apply JSON Patch documents to JSON data.

input.json
patch.json
output.json

About JSON Patch

Apply a JSON Patch (RFC 6902) to a document and see the result - handy for testing PATCH requests and config migrations.

🛠️
How to use it
  1. Paste the original document into input.json.
  2. Paste the patch - an array of operations - into patch.json.
  3. Click Apply Patch; the patched document appears in output.json.
  4. Click Load Sample to see a working example.
💡
Tips & use cases
  • Supported operations are add, remove, replace, move, copy and test.
  • Paths are JSON Pointers: /profile/name, and /tags/- appends to an array.
  • A failing test operation stops the patch - useful for guarding against unexpected state.

JSON Patch explained

JSON Patch, defined in RFC 6902, describes changes to a JSON document as a list of operations. Instead of sending a whole new document, you send only what changed - for example "replace the role" and "append a tag". The operations are applied in order, and if any one of them fails, the patch is rejected.

The six operations

Every operation is an object with an op and a path. Some also need a value or a from.

OperationExampleWhat it does
add{ "op": "add", "path": "/email", "value": "ada@example.com" }Adds a property, or inserts into an array at an index (later items shift right). /- appends to the end. If the property already exists, its value is replaced.
remove{ "op": "remove", "path": "/temp" }Removes the value at the path. The target must exist.
replace{ "op": "replace", "path": "/role", "value": "admin" }Replaces the value at the path. The target must exist - use add to create new properties.
move{ "op": "move", "from": "/nick", "path": "/alias" }Removes the value at from and adds it at path. You can't move a value into one of its own children.
copy{ "op": "copy", "from": "/name", "path": "/displayName" }Copies the value at from to path, leaving the original in place.
test{ "op": "test", "path": "/version", "value": 3 }Checks that the value at the path equals value. If it doesn't, the whole patch fails. Use it as a guard before changing data.
📍

Paths are JSON Pointers

  • Paths use JSON Pointer syntax (RFC 6901): each segment is separated by /, so /profile/name is the name property inside profile.
  • Array items are addressed by zero-based index: /tags/0 is the first tag.
  • - means "after the last item" and is only valid with add (and as the target of move or copy).
  • Escape special characters in keys: ~1 for / and ~0 for ~. The key a/b is written /a~1b.
⚖️

JSON Patch vs JSON Merge Patch

  • JSON Merge Patch (RFC 7386) is simpler: you send a partial document, and its values overwrite the original. Setting a key to null deletes it.
  • Merge Patch can't set a value to null, and it replaces arrays as a whole - you can't append or change a single item.
  • JSON Patch handles both, adds move, copy and test, and applies changes in a defined order.
  • Over HTTP, JSON Patch is sent with the content type application/json-patch+json; Merge Patch uses application/merge-patch+json.
🧪

Worked example

Original document

{
  "name": "Ada",
  "role": "viewer",
  "tags": ["beta"],
  "temp": true
}

Patch

[
  { "op": "test", "path": "/role", "value": "viewer" },
  { "op": "replace", "path": "/role", "value": "admin" },
  { "op": "add", "path": "/tags/-", "value": "staff" },
  { "op": "remove", "path": "/temp" },
  { "op": "copy", "from": "/name", "path": "/displayName" }
]

Result

{
  "name": "Ada",
  "role": "admin",
  "tags": ["beta", "staff"],
  "displayName": "Ada"
}

The test runs first: if role had already changed, none of the other operations would be applied.

📋

Common uses

  • Testing the body of an HTTP PATCH request before sending it to an API.
  • Writing Kubernetes JSON patches (kubectl patch --type=json) and checking the result first.
  • Migrating configuration files from one version to the next with a repeatable list of changes.
  • Recording or syncing changes between clients as small diffs instead of full documents.

Frequently asked questions

Why does my patch fail with a path error?

remove, replace and test need the target to exist, and add needs the parent to exist. Check spelling and case (keys are case-sensitive), that array indexes are in range, and that keys containing / or ~ are escaped.

Is a JSON Pointer the same as JSONPath?

No. A JSON Pointer such as /users/0/name addresses exactly one location. JSONPath such as $.users[*].name is a query language with wildcards and filters that can match many values.

Are operations applied in order?

Yes. Each operation sees the document as left by the previous one. For example, after removing /tags/0, the item that was at /tags/1 is now at /tags/0.

How do I find out what changed between two documents?

Paste both into Compare JSON to see every added, removed and changed value, then write the matching operations here.

Is my data sent to a server?

No. The patch is applied in your browser, so your documents never leave your device.