Skip to content

JsonPatch.ts

The JsonPatch module computes and applies deterministic patch documents for JSON values. A patch is an ordered list of add, remove, and replace operations addressed by JSON Pointer paths. Use it to describe the structural difference between two JSON documents, serialize that difference, and replay it without mutating the original input.

Since v4.0.0



A JSON Patch document (an ordered list of operations).

When to use

Use to store, serialize, pass, or validate complete patch documents.

Details

Represents a complete transformation as a readonly sequence of immutable operations. Operations are applied sequentially from first to last, and later operations observe the document state produced by earlier operations. An empty array represents a no-op patch and returns the original document.

Example (Defining a multi-operation patch)

import { JsonPatch } from "effect"
const patch: JsonPatch.JsonPatch = [
{ op: "add", path: "/items/-", value: "apple" },
{ op: "replace", path: "/count", value: 5 },
{ op: "remove", path: "/oldField" }
]
const result = JsonPatch.apply(patch, { count: 3, oldField: "value" })
// { count: 5, items: ["apple"] }

See

  • JsonPatchOperation for individual operation types
  • get to generate patches from value differences
  • apply to execute patches to transform documents

Signature

type JsonPatch = ReadonlyArray<JsonPatchOperation>

Source

Since v4.0.0

A single JSON Patch operation.

When to use

Use to manually construct patch operations, accept patch operations from callers, or type-check patch operation structures.

Details

Represents one transformation step in a JSON Patch document. This is a subset of RFC 6902, restricted to operations that can be applied deterministically without additional context. All fields are readonly, paths use JSON Pointer syntax, and the empty string "" refers to the root document. Operations are discriminated by the op field, and the optional description field can be used for documentation.

Example (Defining all operation types)

import { JsonPatch } from "effect"
const addOp: JsonPatch.JsonPatchOperation = {
op: "add",
path: "/users/-",
value: { id: 1, name: "Alice" }
}
const removeOp: JsonPatch.JsonPatchOperation = {
op: "remove",
path: "/users/0"
}
const replaceOp: JsonPatch.JsonPatchOperation = {
op: "replace",
path: "/users/0/name",
value: "Bob"
}

See

  • JsonPatch for the array of operations forming a complete patch
  • get to compute operations automatically from value differences
  • apply to apply operations to transform documents

Signature

type JsonPatchOperation =
| {
readonly op: "add"
/**
* JSON Pointer to the target location. For arrays, the last token may be `-`
* to append.
*
* **When to use**
*
* Use to identify where the `add` operation inserts its value.
*/
readonly path: string
readonly value: Schema.Json
readonly description?: string
}
| {
readonly op: "remove"
/**
* JSON Pointer to the target location.
*
* **When to use**
*
* Use to identify which location the `remove` operation deletes.
*/
readonly path: string
readonly description?: string
}
| {
readonly op: "replace"
/**
* JSON Pointer to the target location. Use `""` to replace the root document.
*
* **When to use**
*
* Use to identify which location the `replace` operation overwrites.
*/
readonly path: string
readonly value: Schema.Json
readonly description?: string
}

Source

Since v4.0.0

Applies a JSON Patch to a JSON document.

When to use

Use to execute patches generated by get, transform documents with manually constructed patches, or process patch operations from external sources.

Details

Executes patch operations sequentially, so later operations see changes made by earlier operations. It never mutates the input document; array and object operations copy the affected containers. An empty patch returns the original reference, and a root replace (path: "") returns the provided value directly.

Gotchas

Invalid paths, missing properties, and out-of-bounds array indices throw errors.

Example (Applying a patch)

import { JsonPatch } from "effect"
const document = { items: [1, 2, 3], total: 6 }
const patch: JsonPatch.JsonPatch = [
{ op: "add", path: "/items/-", value: 4 },
{ op: "replace", path: "/total", value: 10 }
]
const result = JsonPatch.apply(patch, document)
// { items: [1, 2, 3, 4], total: 10 }

See

  • get to generate patches from value differences
  • JsonPatchOperation for the operation types being applied

Signature

declare const apply: (patch: JsonPatch, oldValue: Schema.Json) => Schema.Json

Source

Since v4.0.0

Computes a structural patch that transforms oldValue into newValue.

When to use

Use to compute a JSON Patch from before and after JSON documents, detect structural changes, or create deterministic update operations.

Details

Generates a structural diff between two JSON values, producing a patch that yields newValue when applied to oldValue. It returns an empty array when values are identical, recursively diffs nested structures, emits root replace operations for primitive changes, and processes object keys in sorted order for stable output.

Gotchas

Arrays are compared by index position, with no move or copy detection. Array removals are emitted from highest to lowest index to prevent index shifting. The output is deterministic but not guaranteed to be minimal.

Example (Computing object diff)

import { JsonPatch } from "effect"
const oldValue = { users: [{ id: 1, name: "Alice" }], count: 1 }
const newValue = {
users: [
{ id: 1, name: "Bob" },
{ id: 2, name: "Charlie" }
],
count: 2
}
const patch = JsonPatch.get(oldValue, newValue)
// [
// { op: "replace", path: "/users/0/name", value: "Bob" },
// { op: "add", path: "/users/1", value: { id: 2, name: "Charlie" } },
// { op: "replace", path: "/count", value: 2 }
// ]

See

  • apply to apply the generated patch to a document
  • JsonPatchOperation for the operation types in the patch

Signature

declare const get: (oldValue: Schema.Json, newValue: Schema.Json) => JsonPatch

Source

Since v4.0.0