or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-microdiff

Small, fast, zero dependency deep object and array comparison

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/microdiff@1.5.x

To install, run

npx @tessl/cli install tessl/npm-microdiff@1.5.0

index.mddocs/

Microdiff

Microdiff is a tiny (<1kb), fast, zero dependency object and array comparison library. It provides a single diff() function that computes differences between JavaScript objects and arrays with full TypeScript support. The library is significantly faster than most other deep comparison libraries and handles cyclical references, special object types like Date and RegExp, and NaN values correctly.

Package Information

  • Package Name: microdiff
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install microdiff

Core Imports

import diff from "microdiff";

For CommonJS:

const diff = require("microdiff").default;

Named imports for TypeScript:

import diff, { 
  type Difference, 
  type DifferenceCreate, 
  type DifferenceRemove, 
  type DifferenceChange 
} from "microdiff";

Basic Usage

import diff from "microdiff";

const obj1 = {
  originalProperty: true,
  nested: { value: 42 }
};
const obj2 = {
  originalProperty: true,
  newProperty: "new",
  nested: { value: 100 }
};

const differences = diff(obj1, obj2);
console.log(differences);
// [
//   { type: "CREATE", path: ["newProperty"], value: "new" },
//   { type: "CHANGE", path: ["nested", "value"], value: 100, oldValue: 42 }
// ]

Capabilities

Object and Array Comparison

The core diff function performs deep comparison between two objects or arrays and returns an array of difference objects describing all changes.

/**
 * Deep comparison function that computes differences between two objects or arrays
 * @param obj - First object/array to compare
 * @param newObj - Second object/array to compare  
 * @param options - Optional configuration object (defaults to { cyclesFix: true })
 * @returns Array of Difference objects describing changes
 */
function diff(
  obj: Record<string, any> | any[],
  newObj: Record<string, any> | any[],
  options?: Partial<{ cyclesFix: boolean }>
): Difference[];

Usage Examples:

import diff from "microdiff";

// Basic object comparison
const result1 = diff(
  { a: 1, b: 2 },
  { a: 1, b: 3, c: 4 }
);
// [
//   { type: "CHANGE", path: ["b"], value: 3, oldValue: 2 },
//   { type: "CREATE", path: ["c"], value: 4 }
// ]

// Array comparison
const result2 = diff([1, 2, 3], [1, 3, 4]);
// [
//   { type: "CHANGE", path: [1], value: 3, oldValue: 2 },
//   { type: "CHANGE", path: [2], value: 4, oldValue: 3 }
// ]

// Nested objects
const result3 = diff(
  { user: { name: "Alice", age: 25 } },
  { user: { name: "Alice", age: 26, active: true } }
);
// [
//   { type: "CHANGE", path: ["user", "age"], value: 26, oldValue: 25 },
//   { type: "CREATE", path: ["user", "active"], value: true }
// ]

// Disable cycle detection for performance
const result4 = diff(obj1, obj2, { cyclesFix: false });

Cyclical Reference Handling

By default, microdiff detects and handles cyclical references to prevent infinite loops during comparison.

// Cyclical references are handled automatically
const obj1 = { a: {} };
obj1.a.parent = obj1;

const obj2 = { a: {} };  
obj2.a.parent = obj2;

const result = diff(obj1, obj2); // Returns [] - objects are equivalent

Special Object Type Support

Microdiff correctly handles special JavaScript object types by comparing their values rather than their internal structure.

// Date objects
const result1 = diff(
  { created: new Date('2023-01-01') },
  { created: new Date('2023-01-02') }
);
// [{ type: "CHANGE", path: ["created"], value: Date('2023-01-02'), oldValue: Date('2023-01-01') }]

// RegExp objects  
const result2 = diff(
  { pattern: /abc/g },
  { pattern: /def/i }
);
// [{ type: "CHANGE", path: ["pattern"], value: /def/i, oldValue: /abc/g }]

Types

Difference Types

/** Union type representing all possible difference operations */
type Difference = DifferenceCreate | DifferenceRemove | DifferenceChange;

/** Represents a CREATE operation (new property added) */
interface DifferenceCreate {
  type: "CREATE";
  /** Path to the created property as an array of keys */
  path: (string | number)[];
  /** Value of the created property */
  value: any;
}

/** Represents a REMOVE operation (property deleted) */
interface DifferenceRemove {
  type: "REMOVE";
  /** Path to the removed property as an array of keys */
  path: (string | number)[];
  /** Previous value of the removed property */
  oldValue: any;
}

/** Represents a CHANGE operation (property value modified) */
interface DifferenceChange {
  type: "CHANGE";
  /** Path to the changed property as an array of keys */
  path: (string | number)[];
  /** New value of the changed property */
  value: any;
  /** Previous value of the changed property */
  oldValue: any;
}

Understanding Paths

The path property in difference objects provides a hierarchical path to the changed property:

  • For objects: Uses string keys (["user", "name"])
  • For arrays: Uses numeric indices ([0, "property"])
  • For nested structures: Combines both (["users", 1, "profile", "email"])
// Path examples
const obj1 = {
  users: [
    { name: "Alice", profile: { email: "alice@old.com" } }
  ]
};

const obj2 = {
  users: [
    { name: "Alice", profile: { email: "alice@new.com" } }
  ]
};

const result = diff(obj1, obj2);
// [{ 
//   type: "CHANGE", 
//   path: ["users", 0, "profile", "email"], 
//   value: "alice@new.com", 
//   oldValue: "alice@old.com" 
// }]

Advanced Features

NaN Handling

Microdiff treats NaN values as equivalent during comparison, which differs from JavaScript's default behavior:

const result = diff({ value: NaN }, { value: NaN });
// Returns [] - NaN values are considered equal

Performance Optimization

For objects without cyclical references (like parsed JSON), disable cycle detection for better performance:

// ~49% faster when cycles detection is disabled
const result = diff(jsonObj1, jsonObj2, { cyclesFix: false });

Platform Support

Microdiff runs on all modern JavaScript environments:

  • Node.js (CommonJS and ES modules)
  • Deno: import diff from "https://deno.land/x/microdiff@1.5.0/index.ts"
  • Bun
  • Web browsers
  • Service workers
  • TypeScript projects (includes full type definitions)