Gathering detailed insights and metrics for @ziflow/json-diff-ts
Gathering detailed insights and metrics for @ziflow/json-diff-ts
Gathering detailed insights and metrics for @ziflow/json-diff-ts
Gathering detailed insights and metrics for @ziflow/json-diff-ts
A diff tool for JavaScript written in TypeScript.
npm install @ziflow/json-diff-ts
Typescript
Module System
Node Version
NPM Version
TypeScript (98.49%)
JavaScript (1.51%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
140 Stars
433 Commits
27 Forks
2 Watchers
22 Branches
13 Contributors
Updated on Jul 08, 2025
Latest Version
1.2.6
Package Id
@ziflow/json-diff-ts@1.2.6
Unpacked Size
33.26 kB
Size
8.48 kB
File Count
9
NPM Version
8.19.2
Node Version
16.18.1
Published on
Feb 17, 2023
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
1
Modern TypeScript JSON diff library - json-diff-ts
is a lightweight, high-performance TypeScript library for calculating and applying differences between JSON objects. Perfect for modern web applications, state management, data synchronization, and real-time collaborative editing.
This library is particularly valuable for applications where tracking changes in JSON data is crucial, such as state management systems, form handling, or data synchronization.
1npm install json-diff-ts
1import { diff, applyChangeset } from 'json-diff-ts'; 2 3// Two versions of data 4const oldData = { name: 'Luke', level: 1, skills: ['piloting'] }; 5const newData = { name: 'Luke Skywalker', level: 5, skills: ['piloting', 'force'] }; 6 7// Calculate differences 8const changes = diff(oldData, newData); 9console.log(changes); 10// Output: [ 11// { type: 'UPDATE', key: 'name', value: 'Luke Skywalker', oldValue: 'Luke' }, 12// { type: 'UPDATE', key: 'level', value: 5, oldValue: 1 }, 13// { type: 'ADD', key: 'skills', value: 'force', embeddedKey: '1' } 14// ] 15 16// Apply changes to get the new object 17const result = applyChangeset(oldData, changes); 18console.log(result); // { name: 'Luke Skywalker', level: 5, skills: ['piloting', 'force'] }
TypeScript / ES Modules:
1import { diff } from 'json-diff-ts';
CommonJS:
1const { diff } = require('json-diff-ts');
diff
Generates a difference set for JSON objects. When comparing arrays, if a specific key is provided, differences are determined by matching elements via this key rather than array indices.
1import { diff } from 'json-diff-ts'; 2 3// State during A New Hope - Desert planet, small rebel cell 4const oldData = { 5 location: 'Tatooine', 6 mission: 'Rescue Princess', 7 status: 'In Progress', 8 characters: [ 9 { id: 'LUKE_SKYWALKER', name: 'Luke Skywalker', role: 'Farm Boy', forceTraining: false }, 10 { id: 'LEIA_ORGANA', name: 'Princess Leia', role: 'Prisoner', forceTraining: false } 11 ], 12 equipment: ['Lightsaber', 'Blaster'] 13}; 14 15// State after successful rescue - Base established, characters evolved 16const newData = { 17 location: 'Yavin Base', 18 mission: 'Destroy Death Star', 19 status: 'Complete', 20 characters: [ 21 { id: 'LUKE_SKYWALKER', name: 'Luke Skywalker', role: 'Pilot', forceTraining: true, rank: 'Commander' }, 22 { id: 'HAN_SOLO', name: 'Han Solo', role: 'Smuggler', forceTraining: false, ship: 'Millennium Falcon' } 23 ], 24 equipment: ['Lightsaber', 'Blaster', 'Bowcaster', 'X-wing Fighter'] 25}; 26 27const diffs = diff(oldData, newData, { embeddedObjKeys: { characters: 'id' } }); 28console.log(diffs); 29// First operations: 30// [ 31// { type: 'UPDATE', key: 'location', value: 'Yavin Base', oldValue: 'Tatooine' }, 32// { type: 'UPDATE', key: 'mission', value: 'Destroy Death Star', oldValue: 'Rescue Princess' }, 33// { type: 'UPDATE', key: 'status', value: 'Complete', oldValue: 'In Progress' }, 34// ... 35// ]
1import { diff } from 'json-diff-ts'; 2 3// Using nested paths for sub-arrays 4const diffs = diff(oldData, newData, { embeddedObjKeys: { 'characters.equipment': 'id' } }); 5 6// Designating root with '.' - useful for complex nested structures 7const diffs = diff(oldData, newData, { embeddedObjKeys: { '.characters.allies': 'id' } });
1import { diff } from 'json-diff-ts'; 2 3// Control how type changes are treated 4const diffs = diff(oldData, newData, { treatTypeChangeAsReplace: false });
Date objects can now be updated to primitive values without errors when treatTypeChangeAsReplace
is set to false
.
1import { diff } from 'json-diff-ts'; 2 3// Skip specific nested paths from comparison - useful for ignoring metadata 4const diffs = diff(oldData, newData, { keysToSkip: ['characters.metadata'] });
1import { diff } from 'json-diff-ts'; 2 3// Use function to resolve object keys dynamically 4const diffs = diff(oldData, newData, { 5 embeddedObjKeys: { 6 characters: (obj, shouldReturnKeyName) => (shouldReturnKeyName ? 'id' : obj.id) 7 } 8});
1import { diff } from 'json-diff-ts'; 2 3// Use regex for path matching - powerful for dynamic property names 4const embeddedObjKeys = new Map(); 5embeddedObjKeys.set(/^characters/, 'id'); // Match any property starting with 'characters' 6const diffs = diff(oldData, newData, { embeddedObjKeys });
1import { diff } from 'json-diff-ts'; 2 3// Compare string arrays by value instead of index - useful for tags, categories 4const diffs = diff(oldData, newData, { embeddedObjKeys: { equipment: '$value' } });
atomizeChangeset
and unatomizeChangeset
Transform complex changesets into a list of atomic changes (and back), each describable by a JSONPath.
1import { atomizeChangeset, unatomizeChangeset } from 'json-diff-ts'; 2 3// Create atomic changes 4const atomicChanges = atomizeChangeset(diffs); 5 6// Restore the changeset from a selection of atomic changes 7const changeset = unatomizeChangeset(atomicChanges.slice(0, 3));
Atomic Changes Structure:
1[ 2 { 3 type: 'UPDATE', 4 key: 'location', 5 value: 'Yavin Base', 6 oldValue: 'Tatooine', 7 path: '$.location', 8 valueType: 'String' 9 }, 10 { 11 type: 'UPDATE', 12 key: 'mission', 13 value: 'Destroy Death Star', 14 oldValue: 'Rescue Princess', 15 path: '$.mission', 16 valueType: 'String' 17 }, 18 { 19 type: 'ADD', 20 key: 'rank', 21 value: 'Commander', 22 path: "$.characters[?(@.id=='LUKE_SKYWALKER')].rank", 23 valueType: 'String' 24 }, 25 { 26 type: 'ADD', 27 key: 'HAN_SOLO', 28 value: { id: 'HAN_SOLO', name: 'Han Solo', role: 'Smuggler', forceTraining: false, ship: 'Millennium Falcon' }, 29 path: "$.characters[?(@.id=='HAN_SOLO')]", 30 valueType: 'Object' 31 } 32]
applyChangeset
and revertChangeset
Apply or revert changes to JSON objects.
1import { applyChangeset, revertChangeset } from 'json-diff-ts'; 2 3// Apply changes 4const updated = applyChangeset(oldData, diffs); 5console.log(updated); 6// { location: 'Yavin Base', mission: 'Destroy Death Star', status: 'Complete', ... } 7 8// Revert changes 9const reverted = revertChangeset(newData, diffs); 10console.log(reverted); 11// { location: 'Tatooine', mission: 'Rescue Princess', status: 'In Progress', ... }
Function | Description | Parameters |
---|---|---|
diff(oldObj, newObj, options?) | Generate differences between two objects | oldObj : Original objectnewObj : Updated objectoptions : Optional configuration |
applyChangeset(obj, changeset) | Apply changes to an object | obj : Object to modifychangeset : Changes to apply |
revertChangeset(obj, changeset) | Revert changes from an object | obj : Object to modifychangeset : Changes to revert |
atomizeChangeset(changeset) | Convert changeset to atomic changes | changeset : Nested changeset |
unatomizeChangeset(atomicChanges) | Convert atomic changes back to nested changeset | atomicChanges : Array of atomic changes |
Function | Description | Parameters |
---|---|---|
compare(oldObj, newObj) | Create enriched comparison object | oldObj : Original objectnewObj : Updated object |
enrich(obj) | Create enriched representation of object | obj : Object to enrich |
createValue(value) | Create value node for comparison | value : Any value |
createContainer(value) | Create container node for comparison | value : Object or Array |
1interface Options { 2 embeddedObjKeys?: Record<string, string | Function> | Map<string | RegExp, string | Function>; 3 keysToSkip?: string[]; 4 treatTypeChangeAsReplace?: boolean; 5}
Option | Type | Description |
---|---|---|
embeddedObjKeys | `Record<string, string | Function>or Map<string |
keysToSkip | string[] | Dotted paths to exclude from comparison, e.g. "meta.info" . |
treatTypeChangeAsReplace | boolean | When true (default), a type change results in a REMOVE/ADD pair. Set to false to treat it as an UPDATE. |
1enum Operation { 2 REMOVE = 'REMOVE', 3 ADD = 'ADD', 4 UPDATE = 'UPDATE' 5}
v4.8.1: Improved documentation with working examples and detailed options.
v4.8.0: Significantly reduced bundle size by completely removing es-toolkit dependency and implementing custom utility functions. This change eliminates external dependencies while maintaining identical functionality and improving performance.
v4.7.0: Optimized bundle size and performance by replacing es-toolkit/compat with es-toolkit for difference, intersection, and keyBy functions
v4.6.3: Fixed null comparison returning update when values are both null (fixes issue #284)
v4.6.2: Fixed updating to null when treatTypeChangeAsReplace
is false and bumped Jest dev dependencies
v4.6.1: Consistent JSONPath format for array items (fixes issue #269)
v4.6.0: Fixed filter path regex to avoid polynomial complexity
v4.5.1: Updated package dependencies
v4.5.0: Switched internal utilities from lodash to es-toolkit/compat for a smaller bundle size
v4.4.0: Fixed Date-to-string diff when treatTypeChangeAsReplace
is false
v4.3.0: Enhanced functionality:
v4.2.0: Improved stability with multiple fixes:
v4.1.0: Full support for ES modules while maintaining CommonJS compatibility
v4.0.0: Changed naming of flattenChangeset and unflattenChanges to atomizeChangeset and unatomizeChangeset; added option to set treatTypeChangeAsReplace
v3.0.1: Fixed issue with unflattenChanges when a key has periods
v3.0.0: Added support for both CommonJS and ECMAScript Modules. Replaced lodash-es with lodash to support both module formats
v2.2.0: Fixed lodash-es dependency, added exclude keys option, added string array comparison by value
v2.1.0: Fixed JSON Path filters by replacing single equal sign (=) with double equal sign (==). Added support for using '.' as root in paths
v2.0.0: Upgraded to ECMAScript module format with optimizations and improved documentation. Fixed regex path handling (breaking change: now requires Map instead of Record for regex paths)
v1.2.6: Enhanced JSON Path handling for period-inclusive segments
v1.2.5: Added key name resolution support for key functions
v1.2.4: Documentation updates and dependency upgrades
v1.2.3: Updated dependencies and TypeScript
Contributions are welcome! Please follow the provided issue templates and code of conduct.
Feature | json-diff-ts | deep-diff | jsondiffpatch |
---|---|---|---|
TypeScript | ✅ Native | ❌ Partial | ❌ Definitions only |
Bundle Size | 🟢 21KB | 🟡 45KB | 🔴 120KB+ |
Dependencies | 🟢 Zero | 🟡 Few | 🔴 Many |
ESM Support | ✅ Native | ❌ CJS only | ❌ CJS only |
Array Key Matching | ✅ Advanced | ❌ Basic | ✅ Advanced |
JSONPath Support | ✅ Full | ❌ None | ❌ Limited |
Q: Can I use this with React/Vue/Angular?
A: Yes! json-diff-ts works with any JavaScript framework or vanilla JS.
Q: Does it work with Node.js?
A: Absolutely! Supports Node.js 18+ with both CommonJS and ES modules.
Q: How does it compare to JSON Patch (RFC 6902)?
A: json-diff-ts provides a more flexible format with advanced array handling, while JSON Patch is a standardized format.
Q: Is it suitable for large objects?
A: Yes, the library is optimized for performance and can handle large, complex JSON structures efficiently.
Reach out to the maintainer:
Discover more about the company behind this project: hololux
This project takes inspiration and code from diff-json by viruschidai@gmail.com.
json-diff-ts is open-sourced software licensed under the MIT license.
The original diff-json project is also under the MIT License. For more information, refer to its license details.
No vulnerabilities found.
Reason
30 commit(s) and 7 issue activity found in the last 90 days -- score normalized to 10
Reason
no binaries found in the repo
Reason
no dangerous workflow patterns detected
Reason
license file detected
Details
Reason
SAST tool is run on all commits
Details
Reason
1 existing vulnerabilities detected
Details
Reason
dependency not pinned by hash detected -- score normalized to 4
Details
Reason
Found 0/5 approved changesets -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Score
Last Scanned on 2025-07-07
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More