JSON‑Atom Format is a language-agnostic format for representing atomic changes to JSON documents.
It defines five operations — add, remove, replace, move, and copy — addressed by JSONPath-based paths that support identity-based array element selection. This is the key capability that sets JSON‑Atom Format apart from existing standards like RFC 6902 (JSON Patch) and RFC 7396 (JSON Merge Patch).
Rather than storing full JSON snapshots, systems can record a sequence of structured change operations and reconstruct state at any point in time. A JSON document can therefore be treated as a materialized view over an ordered sequence of delta operations.
Quick Example
Source document:
{
"user": { "name": "Alice", "email": "alice@example.com" },
"items": [
{ "id": "1", "name": "Widget", "price": 10 },
{ "id": "2", "name": "Gadget", "price": 20 }
]
}Target document:
{
"user": { "name": "Anna", "email": "alice@example.com", "role": "admin" },
"items": [
{ "id": "1", "name": "Widget Pro", "price": 15 },
{ "id": "3", "name": "Thingamajig", "price": 40 }
]
}JSON‑Atom Format:
{
"format": "json-atom",
"version": 1,
"operations": [
{ "op": "replace", "path": "$.user.name", "value": "Anna", "oldValue": "Alice" },
{ "op": "add", "path": "$.user.role", "value": "admin" },
{ "op": "replace", "path": "$.items[?(@.id=='1')].name", "value": "Widget Pro", "oldValue": "Widget" },
{ "op": "replace", "path": "$.items[?(@.id=='1')].price", "value": 15, "oldValue": 10 },
{ "op": "remove", "path": "$.items[?(@.id=='2')]",
"oldValue": { "id": "2", "name": "Gadget", "price": 20 } },
{ "op": "add", "path": "$.items[?(@.id=='3')]",
"value": { "id": "3", "name": "Thingamajig", "price": 40 } }
]
}Note how array elements are addressed by key-based identity (@.id=='1') rather than by positional index. This makes deltas resilient to reordering and meaningful across systems that don't share array positions.
Why JSON‑Atom Format?
vs. RFC 6902 (JSON Patch)
RFC 6902 uses RFC 6901 JSON Pointer for paths, which addresses array elements only by index (/items/0). If an array is reordered or an element is inserted, every index-based path may become invalid.
JSON‑Atom Format uses JSONPath filter expressions ($.items[?(@.id=='1')]) to address array elements by a stable identity key. This is the fundamental capability gap that JSON‑Atom Format fills.
vs. RFC 7396 (JSON Merge Patch)
RFC 7396 merges changes by overlaying partial documents. It cannot represent null as a value (it means "delete"), cannot express array element changes atomically, and cannot produce reversible changesets.
JSON‑Atom Format represents each change as a discrete, atomic operation with an explicit path. It supports null as a first-class value and enables reversibility through optional oldValue fields.
Summary
| Capability | RFC 6902 | RFC 7396 | JSON‑Atom Format |
|---|---|---|---|
| Atomic operations | Yes | No | Yes |
| Array identity by key | No | No | Yes |
| Move / Copy | Yes | No | Yes |
| Reversible | No | No | Yes (with oldValue) |
null as value |
Yes | No | Yes |
| Self-identifying document | No | No | Yes (format field) |
| Extensible | No | No | Yes (x_ properties) |
Operations
| Operation | Description | Required fields | Optional fields |
|---|---|---|---|
add |
Add a value at a path that does not exist | op, path, value |
|
remove |
Remove a value at a path that exists | op, path |
oldValue |
replace |
Replace the value at a path with a new value | op, path, value |
oldValue |
move |
Move a value from one path to another | op, from, path |
|
copy |
Copy a value from one path to another | op, from, path |
value |
valuealways means the new value (present onaddandreplace; optional oncopyfor reversibility).oldValuealways means the previous value (present onremoveandreplacefor reversible deltas).fromis the source path formoveandcopyoperations.- A delta is reversible when every
replace/removeincludesoldValueand everycopyincludesvalue.
Move atomically removes a value from from and adds it at path. Inversion is symmetric: move(from, path) → move(path, from).
Copy reads a value at from and deep-clones it to path. The source is unchanged. The optional value field enables reversibility (the inverse is remove at path).
Delta Document Structure
{
"format": "json-atom",
"version": 1,
"operations": [ ... ]
}| Field | Type | Required | Description |
|---|---|---|---|
format |
string | Yes | Must be "json-atom". Self-identifying discriminator. |
version |
integer | Yes | Format version. Currently 1. |
operations |
array | Yes | Ordered array of operation objects. |
Additional properties are allowed and preserved. Properties prefixed with x_ are reserved for extensions and will never conflict with future spec versions.
JSON‑Atom Path
JSON‑Atom Format uses a constrained subset of JSONPath (RFC 9535) with six productions:
| Production | Example | Description |
|---|---|---|
| Root | $ |
The entire document |
| Dot property | $.user.name |
Object property access |
| Bracket property | $['a.b'] |
Property with special characters |
| Array index | $.items[0] |
Zero-based positional index |
| Key filter | $.items[?(@.id==42)] |
Identity by object property |
| Value filter | $.tags[?(@=='urgent')] |
Identity by primitive value |
Canonical form: Dot notation for safe identifiers ([a-zA-Z_][a-zA-Z0-9_]*), bracket notation for everything else. Array indices always use brackets.
Filter literals: String ('val'), number (42), boolean (true/false), null. Comparison uses JSON value equality — type and value must match.
Design Goals
JSON‑Atom Format is designed to be:
- Deterministic — The same inputs produce the same logical delta.
- Atomic — Each operation targets exactly one location.
- Language-agnostic — Suitable for TypeScript, Python, .NET, and beyond.
- Replay-friendly — Ordered deltas reconstruct document state over time.
- Self-identifying — The
formatfield enables detection without inspecting internals. - Extension-friendly — Unknown properties are preserved;
x_-prefixed properties are future-safe.
Non-Goals
JSON‑Atom Format intentionally does not define:
- A diff algorithm (how to compute deltas)
- A comparison strategy (how to detect semantic changes)
- Conflict resolution or merge semantics
- Transport or storage protocols
Use Cases
- Change tracking — Record what changed, when, and (via extensions) by whom.
- Replayable state history — Reconstruct any past document state from an initial snapshot plus ordered deltas.
- State synchronization — Exchange minimal change descriptions between systems.
- Audit trails — Immutable, structured records of every modification.
- AI agent state tracking — Inspect and replay agent execution step by step.
- Time-travel debugging — Navigate forward and backward through state evolution.
Extensibility
JSON‑Atom Format supports extensions through additional properties on both the envelope and individual operations:
{
"format": "json-atom",
"version": 1,
"operations": [
{
"op": "replace",
"path": "$.summary",
"value": "Revenue declined 15%...",
"oldValue": "Revenue grew strongly...",
"x_comparison": { "strategy": "semantic-embedding", "similarity": 0.42 }
}
],
"x_agent": "financial-analyst-v2",
"x_workflow_step": 3
}- Properties prefixed with
x_are guaranteed to never conflict with future spec versions. - Conformant implementations must preserve unknown properties and must not reject them.
Specification
The full draft specification is at spec/v0.md.
Conformance test fixtures are in fixtures/.
Implementations
- json-diff-ts — TypeScript library for computing, applying, and reverting JSON changesets. The originating implementation from which JSON‑Atom Format was derived.
- json-atom — Python library implementing the full JSON‑Atom Format v0 specification. Level 2 (Reversible) conformance.
Specification Status
Draft v0 — JSON‑Atom Format is a draft specification. The core format is stable, but details may evolve before a v1 release. Feedback and contributions are welcome.
License
MIT