A zero dependency, high-performance, security-conscious JavaScript diffing library for comparing complex data structures with ease.
- ⚡️ Zero dependencies – lightweight and no external libraries required
- 📝 Detects additions, deletions, and modifications
- 💡 Supports Primitives, Objects, Arrays, Maps, and Sets
- 🔄 Handles circular references safely
- 🛠️ Highly configurable to fit different use cases
- 🚨 Built with security in mind to prevent prototype pollution and other risks
- 💻 Works in both Node.js and browser environments
npm install @sandboxed/diff
yarn add @sandboxed/diff
Works with both ESM (import
) and CJS (require
). Use the syntax that matches your environment:
// ESM
import diff, { ChangeType } from '@sandboxed/diff';
// CJS option 1
const diff = require('@sandboxed/diff').default;
const { ChangeType } = require('@sandboxed/diff');
// CJS option 2
const { default: diff, ChangeType } = require('@sandboxed/diff');
import diff, { ChangeType } from '@sandboxed/diff';
const a = { name: "Alice", age: 25 };
const b = { name: "Alice", age: 26, city: "New York" };
const result = diff(a, b);
console.log(result);
console.log(result.toDiffString());
console.log(result.equal); // false
Output:
[
{ type: 'noop', str: '{', depth: 0, path: [] },
{
type: 'noop',
str: '"name": "Alice",',
depth: 1,
path: [ 'name', { deleted: false, value: 'Alice' } ]
},
{
type: 'remove',
str: '"age": 25,',
depth: 1,
path: [ 'age', { deleted: true, value: 25 } ]
},
{
type: 'update',
str: '"age": 26,',
depth: 1,
path: [ 'age', { deleted: false, value: 26 } ]
},
{
type: 'add',
str: '"city": "New York",',
depth: 1,
path: [ 'city', { deleted: false, value: 'New York' } ]
},
{ type: 'noop', str: '}', depth: 0, path: [] }
]
// ---
{
"name": "Alice",
- "age": 25,
! "age": 26,
+ "city": "New York",
}
option | Description |
---|---|
config.include | Include only these change types from the diff result. Can be combined with exclude . |
config.exclude | Excludes the change types from the diff result. Can be combined with include . |
config.strict | Performs loose type check if disabled. |
config.showUpdatedOnly | @sandboxed/diff creates a ChangeType.REMOVE entry for every ChangeType.UPDATE . This flags prevents this behavior. |
config.pathHints | Hashmap of map and set path hints. These strings will be used in the path array to provide a hit about the object's type. |
config.redactKeys | List of keys that should be redacted from the output. Works with string based keys and serialized Symbol . |
config.maxDepth | Max depth that the diffing function can traverse. |
config.maxKeys | Max keys the diffing function can traverse. |
config.timeout | Milliseconds before throwing a timeout error. |
util | Description |
---|---|
toDiffString | Generates the diff string representation of the diff result. |
equal | Determines whether the inputs are structurally equal based on the diff result. |
Many diffing libraries are optimized for either structured output or human-readable text, but rarely both. @sandboxed/diff
is designed to provide a structured diff result along with a utility to generate a string representation, making it easy to use in both programmatic logic and UI rendering.
Trade-off: It may be slower than other libraries, but if you prioritize structured diffs with a built-in string representation, @sandboxed/diff
is a great fit.