| Crates.io | spatch |
| lib.rs | spatch |
| version | 0.3.0 |
| created_at | 2025-12-26 10:55:11.342932+00 |
| updated_at | 2025-12-26 13:48:31.549819+00 |
| description | JSON Patch (RFC 6902) library and CLI with optional schema-aware paths for stable array element addressing |
| homepage | |
| repository | https://github.com/kamilczerw/spatch |
| max_upload_size | |
| id | 2005566 |
| size | 204,920 |
A Rust library and CLI for working with JSON Patch (RFC 6902) that adds optional, schema‑aware paths for stable array element addressing, while always producing and consuming standard JSON Patch operations.
This tool solves a common problem with JSON Patch: array elements are addressed by index, which makes diffs fragile and patches noisy when arrays are reordered or elements are inserted/removed. When a JSON Schema is available, this crate allows you to address array elements by semantic identity (e.g. a key field), and compiles those paths down to ordinary RFC 6902 patches.
RFC 6902 remains the wire format - Generated patches are always valid JSON Patch. No extensions, no custom ops.
Semantic paths are optional and schema-enhanced Semantic array paths can be resolved without a schema (as long as the JSON contains the referenced key/value), but a JSON Schema is used to generate schema-aware diffs (and to disambiguate/validate identity rules when needed). Without a schema, diff output is standard index-based JSON Patch.
Array elements are addressed by identity, not position Example semantic path:
/arr/[id=foo]/bar
Given the JSON:
{
"arr": [{ "id": "foo", "bar": "baz" }]
}
There are 2 ways to use this crate - as cli or as a library.
The query language is a standard JSON Pointer with added support for resolving array elements by their identity properties. For example, given the following JSON:
{
"list": [
{ "id": "item-1", "name": "Item 1", "value": 10 },
{ "id": "item-2", "name": "Item 2", "value": 20 }
]
}
You can query by json pointer:
cat examples/simple.json | spatch query '/list/0'
Or by semantic path:
cat examples/simple.json | spatch query '/list/[id=item-1]'
The 2 above commands will output the same result:
{ "id": "item-1", "name": "Item 1", "value": 10 }
You can also read the leaf value directly:
cat examples/simple.json | spatch query '/list/[id=item-1]/value'
The diff command generates a JSON Patch between 2 JSON documents.
It operates in 2 modes - pure RFC 6902 mode (index-based array addressing),
or schema-aware mode (semantic array addressing).
By default, spatch diff operates in pure RFC 6902 mode:
spatch diff examples/simple.json examples/simple-new.json
Will output a standard JSON Patch with index-based array paths.
[
{
"op": "replace",
"path": "/list/1",
"value": {
"id": "item-2",
"name": "Item Two",
"value": 200
}
}
]
To use the schema-aware mode, provide a JSON Schema with identity definitions
spatch diff --schema examples/simple.schema.json examples/simple.json examples/simple-new.json
Will produce a JSON Patch with semantic array paths:
[
{
"op": "replace",
"path": "/list/[id=item-2]",
"value": {
"id": "item-2",
"name": "Item Two",
"value": 200
}
}
]
[!IMPORTANT]
To let spatch know which property to use as identity key for array elements, you MUST provide a JSON Schema that defines the array with
indexKey: "{identity-property-name}". Otherwise, spatch will fall back to index-based addressing.
JSON Patch is a solid standard, but index‑based array addressing is brittle:
This crate keeps JSON Patch unchanged, but uses JSON Schema to recover semantic identity for array elements, producing patches that are: