Skip to content
This repository was archived by the owner on Dec 10, 2025. It is now read-only.
/ zen-json-patch Public archive

πŸ”§ JSON Patch utilities for Zen - RFC 6902 compliant state updates

License

Notifications You must be signed in to change notification settings

SylphxAI/zen-json-patch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

17 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

zen-json-patch ⚑

Monstrously fast TypeScript library for generating JSON Patch (RFC 6902) diffs

npm version License TypeScript

ARCHIVED β€’ RFC 6902 compliant β€’ Type-safe β€’ Zero dependencies β€’ Blazing fast

Installation β€’ Quick Start β€’ API β€’ Benchmarks


⚠️ ARCHIVED

This project is archived and no longer actively maintained.

Recommended alternative: Use @sylphx/craft instead, which provides comprehensive immutable state management with JSON Patch support built-in.


πŸš€ Overview

A high-performance TypeScript library for generating JSON Patch operations (RFC 6902) by comparing two JSON objects. Designed to be significantly faster than existing libraries, especially for large or complex objects.

The Problem:

Traditional JSON diff libraries:
- Slow for large objects ❌
- Heavy dependencies ❌
- Complex APIs ❌
- Limited TypeScript support ❌

The Solution:

zen-json-patch:
- Optimized diff algorithm βœ…
- Zero runtime dependencies βœ…
- Simple, intuitive API βœ…
- Full TypeScript type safety βœ…

Result: Fast, reliable JSON diffing for modern applications.


⚑ Key Features

Performance

Feature Description Benefit
Optimized algorithm Efficient recursive comparison Fast even for large objects
Smart object handling Set-based key lookups O(1) key existence checks
Early exits Strict equality checks first Skip unnecessary comparisons
Zero dependencies Pure TypeScript Minimal bundle size

Standards & Safety

  • RFC 6902 compliant - Generates standard JSON Patch operations
  • Type-safe - Full TypeScript support with strict types
  • Tested - Comprehensive test suite with edge cases
  • Reliable - Handles nested objects, arrays, null, and primitives

πŸ“¦ Installation

# npm
npm install zen-json-patch

# yarn
yarn add zen-json-patch

# pnpm
pnpm add zen-json-patch

# bun
bun add zen-json-patch

πŸš€ Quick Start

Basic Usage

import { diff } from 'zen-json-patch';

const obj1 = { a: 1, b: "hello", c: true };
const obj2 = { a: 2, b: "hello", d: false };

const operations = diff(obj1, obj2);

console.log(operations);
// Output:
// [
//   { op: 'replace', path: '/a', value: 2 },
//   { op: 'remove', path: '/c' },
//   { op: 'add', path: '/d', value: false }
// ]

Nested Objects

const before = {
  user: {
    name: "Alice",
    age: 30,
    address: { city: "NYC" }
  }
};

const after = {
  user: {
    name: "Alice",
    age: 31,
    address: { city: "SF", zip: "94102" }
  }
};

const patch = diff(before, after);
// [
//   { op: 'replace', path: '/user/age', value: 31 },
//   { op: 'replace', path: '/user/address/city', value: 'SF' },
//   { op: 'add', path: '/user/address/zip', value: '94102' }
// ]

Arrays

const arr1 = { items: [1, 2, 3] };
const arr2 = { items: [1, 3, 4] };

const patch = diff(arr1, arr2);
// [
//   { op: 'replace', path: '/items/1', value: 3 },
//   { op: 'replace', path: '/items/2', value: 4 }
// ]

Identical Objects

const obj = { a: 1, b: 2 };
const patch = diff(obj, obj);
// [] (empty - no changes)

πŸ“– API Reference

diff(obj1, obj2): Operation[]

Compares two JSON-compatible objects and generates an array of JSON Patch operations.

Parameters:

  • obj1 (any) - The source object
  • obj2 (any) - The target object

Returns: Operation[] - Array of JSON Patch operations

Operations Generated:

  • add - New property added
  • remove - Property removed
  • replace - Property value changed

Example:

const operations = diff(
  { name: "Alice", age: 30 },
  { name: "Bob", age: 30 }
);
// [{ op: 'replace', path: '/name', value: 'Bob' }]

🎯 Operation Types

JSON Patch Operations (RFC 6902)

type Operation =
  | { op: 'add', path: string, value: any }
  | { op: 'remove', path: string }
  | { op: 'replace', path: string, value: any }
  // move and copy operations not yet implemented

Path Format

Paths use JSON Pointer syntax (RFC 6901):

'/'           // Root
'/a'          // Property 'a'
'/a/b'        // Nested property
'/items/0'    // Array index 0
'/a~0b'       // Property 'a~b' (escaped tilde)
'/a~1b'       // Property 'a/b' (escaped slash)

πŸ“Š Benchmarks

Performance Comparison

Benchmarked against popular JSON diff libraries:

Library Simple Objects Nested Objects Large Objects (1000 keys)
zen-json-patch ⚑ Fast ⚑ Fast ⚑ Fast
fast-json-patch βœ… Good βœ… Good ⚠️ Slower
just-diff βœ… Good ⚠️ Slower ⚠️ Slower
fast-json-diff ⚠️ Slower ⚠️ Slower ⚠️ Slower

Run benchmarks:

npm run bench

Bundle Size

npm run size

Zero runtime dependencies = smaller bundle size.


πŸ” Current Status & Limitations

βœ… Supported

  • Objects - Nested object comparison
  • Arrays - Element-wise comparison
  • Primitives - Numbers, strings, booleans, null
  • Operations - add, remove, replace

⚠️ Limitations

  • Array diffing - Currently uses naive element-wise comparison

    • Correct but not optimized for large insertions/deletions
    • No detection of element moves
    • Planned: Myers diff algorithm for better array performance
  • Operations - move and copy operations not yet generated

    • Could be added as optimizations in future versions

πŸ’‘ Use Cases

State Management

// Track changes in application state
const oldState = store.getState();
// ... state updates ...
const newState = store.getState();

const changes = diff(oldState, newState);
// Send only changes to server or apply to other instances

API Responses

// Efficient incremental updates
const cached = cache.get('user/123');
const fresh = await api.get('user/123');

const delta = diff(cached, fresh);
if (delta.length > 0) {
  cache.update('user/123', delta);
}

Version Control

// Track document changes
const v1 = { title: "Doc", content: "..." };
const v2 = { title: "Document", content: "...", author: "Alice" };

const changelog = diff(v1, v2);
// Store changelog for history/undo

Real-time Sync

// Minimize data transfer
const localData = getLocalData();
const remoteData = fetchRemoteData();

const changes = diff(localData, remoteData);
if (changes.length < remoteData.size * 0.1) {
  // Apply patch (smaller than full data)
  applyPatch(localData, changes);
} else {
  // Replace entirely
  replaceData(remoteData);
}

πŸ—οΈ How It Works

Algorithm Overview

1. Strict equality check
   β”œβ”€ Same reference β†’ No changes
   └─ Different β†’ Continue

2. Type comparison
   β”œβ”€ Different types β†’ Replace
   └─ Same type β†’ Continue

3. Object type check
   β”œβ”€ Arrays β†’ Compare elements
   └─ Objects β†’ Compare properties

4. Object comparison
   β”œβ”€ Iterate obj1 keys
   β”‚  β”œβ”€ Missing in obj2 β†’ Remove
   β”‚  └─ Present β†’ Recurse
   └─ Iterate remaining obj2 keys β†’ Add

5. Array comparison (naive)
   └─ Compare index by index β†’ Replace if different

Example Walkthrough

diff(
  { a: 1, b: { c: 2 } },
  { a: 1, b: { c: 3 }, d: 4 }
)

// Step 1: Root is object, recurse
// Step 2: Check 'a' β†’ Same (1 === 1), skip
// Step 3: Check 'b' β†’ Object, recurse
//   Step 3a: Check 'c' β†’ Different (2 !== 3)
//   Operation: { op: 'replace', path: '/b/c', value: 3 }
// Step 4: Key 'd' in obj2 only
//   Operation: { op: 'add', path: '/d', value: 4 }

// Result:
// [
//   { op: 'replace', path: '/b/c', value: 3 },
//   { op: 'add', path: '/d', value: 4 }
// ]

πŸ§ͺ Development

Setup

# Install dependencies
npm install

# Run tests
npm test

# Watch mode
npm run test:watch

# Run benchmarks
npm run bench

# Build
npm run build

# Check bundle size
npm run size

Project Structure

zen-json-patch/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.ts          # Main diff function
β”‚   β”œβ”€β”€ types.ts          # TypeScript types
β”‚   β”œβ”€β”€ arrayDiff.ts      # Array comparison
β”‚   β”œβ”€β”€ path.ts           # JSON Pointer utilities
β”‚   β”œβ”€β”€ *.spec.ts         # Test files
β”‚   └── rfc6902.spec.ts   # RFC compliance tests
β”œβ”€β”€ bench/
β”‚   β”œβ”€β”€ object-diff.bench.ts
β”‚   └── array-diff.bench.ts
β”œβ”€β”€ package.json
└── tsconfig.json

Testing

Comprehensive test suite covering:

  • βœ… Simple objects
  • βœ… Nested objects
  • βœ… Arrays
  • βœ… Primitives
  • βœ… Edge cases (null, undefined, circular refs)
  • βœ… RFC 6902 compliance

πŸ”§ Configuration

TypeScript

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true
  }
}

Build

Uses tsup for fast, optimized builds:

tsup src/index.ts --format esm,cjs --minify --sourcemap --dts

Output:

  • dist/index.js - CommonJS
  • dist/index.mjs - ES Modules
  • dist/index.d.ts - Type declarations

πŸ“š Resources

JSON Patch Specification

Related Libraries


πŸ—ΊοΈ Roadmap

βœ… Completed

  • Basic object/array comparison
  • RFC 6902 compliant operations
  • TypeScript type safety
  • Comprehensive test suite
  • Benchmarking infrastructure

πŸš€ Planned

  • Optimized array diffing - Myers diff algorithm
  • Move operations - Detect moved elements
  • Copy operations - Optimize duplicate values
  • Patch application - applyPatch() function
  • Performance improvements - Further optimizations
  • Custom comparators - User-defined equality
  • Ignore paths - Skip specific properties

🀝 Contributing

Contributions are welcome! Please follow these guidelines:

  1. Open an issue - Discuss changes before implementing
  2. Fork the repository
  3. Create a feature branch - git checkout -b feature/my-feature
  4. Follow code standards - Run npm run validate
  5. Write tests - Maintain high coverage
  6. Submit a pull request

Development Commands

npm test           # Run tests
npm run bench      # Run benchmarks
npm run build      # Build package
npm run size       # Check bundle size

πŸ“„ License

MIT Β© Sylphx


πŸ™ Credits

Built with:

Inspired by:


πŸ“ž Support


Monstrously fast JSON diffing
RFC 6902 compliant β€’ Type-safe β€’ Zero dependencies

sylphx.com β€’ @SylphxAI β€’ hi@sylphx.com

About

πŸ”§ JSON Patch utilities for Zen - RFC 6902 compliant state updates

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published