fast-json-schema-patch
Version:
Ultra-fast, schema-aware JSON patch generation and human-readable diffing. A high-performance JSON patch library that leverages schema knowledge to generate efficient, semantic patches with tools for creating human-readable diffs suitable for frontend app
184 lines (129 loc) β’ 6.61 kB
Markdown
# fast-json-schema-patch
π Ultra-fast, Schema-Aware JSON Patch Generation with Human-Readable Diffing
fast-json-schema-patch is a high-performance JSON patching library designed to create efficient, schema-driven patches. It intelligently understands your data structure, enabling optimized, semantic diffs, and also provides fast, human-friendly diffing tools for frontend applications. It outperforms many popular alternatives in both speed and memory usage.
π§ Schema-Driven Diffing
Unlike generic JSON diff libraries, fast-json-schema-patch leverages schema-based diff plans to:
- β‘ Optimize array diffing using the best strategy for each case (LCS, primary key matching, etc.).
- π§© Generate semantic patches that align with your dataβs meaning, not just its shape.
- π― Compare objects intelligently by focusing only on relevant fields.
> π‘ Ideal for applications where the JSON structure is known and schema-driven diffs are important.
## π¦ Installation
```bash
bun add fast-json-schema-patch
```
## π Quick Start
The core of the library is the `JsonSchemaPatcher`, which uses a diff plan to optimize patch generation.
```typescript
import { JsonSchemaPatcher, buildPlan } from 'fast-json-schema-patch';
// 1. Define a plan for your data structure, this needs to be done only once for a given schema
const plan = buildPlan({schema});
// 2. Instantiate the patcher with the plan
const patcher = new JsonSchemaPatcher({ plan });
// Original and modified documents
const original = {
users: [
{ id: 'user1', name: 'John Doe', status: 'active' },
{ id: 'user2', name: 'Jane Smith', status: 'inactive' },
],
};
const modified = {
users: [
{ id: 'user1', name: 'John Doe', status: 'online' }, // Changed
{ id: 'user3', name: 'Sam Ray', status: 'active' }, // Added
],
// user2 was removed
};
// 3. Generate the optimized patch
const patch = patcher.execute({original, modified});
console.log(patch);
// Output: [
// { op: "remove", path: "/users/1", oldValue: { id: 'user2', ... } },
// { op: "replace", path: "/users/0/status", value: "online", oldValue: "active" },
// { op: "add", path: "/users/-", value: { id: 'user3', ... } }
// ]
```
### A Note on RFC 6902 Compliance
This library extends the standard JSON Patch format by adding an `oldValue` field to `remove` and `replace` operations.
This addition makes UI rendering and state reconciliation easier but is not part of the strict RFC 6902 specification.
---
## π Generating JSON Schema from Zod
If you're using [Zod](https://zod.dev/) for runtime validation, you can easily generate JSON schemas for use with `fast-json-schema-patch`. Zod 4 introduced native JSON Schema conversion:
```typescript
import * as z from "zod/v4";
import { JsonSchemaPatcher, buildPlan } from 'fast-json-schema-patch';
// Define your Zod schema
const userSchema = z.object({
users: z.array(z.object({
id: z.string(),
name: z.string(),
status: z.enum(['active', 'inactive', 'online'])
}))
});
// Convert Zod schema to JSON Schema
const jsonSchema = z.toJSONSchema(userSchema);
// Use the JSON schema to build a plan
const plan = buildPlan({ schema: jsonSchema });
const patcher = new JsonSchemaPatcher({ plan });
```
This integration makes it seamless to leverage your existing Zod schemas for optimized JSON patching. For more details on Zod's JSON Schema conversion, see the [official documentation](https://zod.dev/json-schema).
---
## π¨ Human-Readable Diffs with `StructuredDiff`
When you need to present diffs to users, raw JSON patches can be hard to work with.
StructuredDiff helps you transform those patches into structured, human-readable diffs that are fast, memory-efficient, and frontend-friendly.
It organizes changes into:
Parent diffs: Changes outside of specific arrays.
Child diffs: Changes within a target array, keyed by unique identifiers.
This makes it easy to build side-by-side diff views or activity feeds.
```typescript
import { StructuredDiff } from 'fast-json-schema-patch';
// Assuming `original`, `modified`, `patch`, and `plan` from the previous example
// 1. Instantiate the aggregator with the plan
const structuredDiff = new StructuredDiff({plan});
// 2. Execute the aggregation
const aggregatedResult = structuredDiff.execute({
original,
modified,
pathPrefix: '/users',
});
// 3. Use the result to render a UI
console.log(aggregatedResult.parentDiff); // Shows changes outside the /users array
console.log(aggregatedResult.childDiffs['user2']); // Shows user2 was removed
console.log(aggregatedResult.childDiffs['user3']); // Shows user3 was added
```
## π οΈ API Reference
### `buildPlan`
Creates a plan for optimizing JSON patch generation based on a JSON schema.
**`buildPlan(options)`**
- `options`: An object with the following properties:
- `schema`: A JSON Schema object that describes your data structure.
- `primaryKeyMap` (optional): A record mapping path prefixes to primary key field names.
- `basePath` (optional): The base path for the schema traversal.
- **Returns**: A `Plan` object that can be used with `JsonSchemaPatcher` and `StructuredDiff`.
### `JsonSchemaPatcher`
The main class for generating patches.
**`new JsonSchemaPatcher({ plan })`**
- `plan`: A `Plan` object created by `buildPlan` that describes your data structure and desired diffing strategies.
**`patcher.execute({original, modified})`**
- `original`: The original document to compare from.
- `modified`: The modified document to compare to.
- **Returns**: An array of JSON Patch operations.
### `StructuredDiff`
The main class for creating human-readable diffs.
**`new StructuredDiff({plan})`**
- `plan`: A `Plan` object created by `buildPlan` that describes your data structure and desired diffing strategies.
**`structuredDiff.execute(config)`**
- `config`: An `StructuredDiffConfig` object with the following properties:
- `pathPrefix`: The path prefix of the array to aggregate (e.g., `/users`).
- `original`: The original document.
- `modified`: The modified document.
- `patches` (optional): Pre-computed patch array from `JsonSchemaPatcher`. If not provided, patches will be generated automatically.
- **Returns**: An `StructuredDiffResult` object containing `parentDiff` and a record of `childDiffs`.
## π¬ Benchmarking Your Use Case
Run benchmarks on your own data:
```bash
# Run the benchmark suite
bun run compare
```
## π Related Standards
- [RFC 6902 - JSON Patch](https://tools.ietf.org/html/rfc6902)
- [JSON Schema Specification](https://json-schema.org/specification.html)