or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-json-diff

JSON structural diff with colorized output and fuzzy array matching

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/json-diff@1.0.x

To install, run

npx @tessl/cli install tessl/npm-json-diff@1.0.0

index.mddocs/

JSON Diff

JSON Diff provides structural comparison of JSON objects and files with colorized, diff-like output. It features fuzzy matching of modified array elements, extensive configuration options, and both programmatic and command-line interfaces.

Package Information

  • Package Name: json-diff
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install json-diff
  • Global Installation: npm install -g json-diff

Core Imports

const { diff, diffString, colorize, colorizeToCallback } = require('json-diff');

ES6 module import:

import { diff, diffString, colorize, colorizeToCallback } from 'json-diff';

Additional exports (from colorize module):

const { colorizeToArray, colorizeToCallback } = require('json-diff/lib/colorize');
// or
import { colorizeToArray, colorizeToCallback } from 'json-diff/lib/colorize';

Note: colorize and colorizeToCallback are available from both the main module and the colorize module, but colorizeToArray is only available from the colorize module.

Basic Usage

const { diff, diffString } = require('json-diff');

// Basic comparison
const obj1 = { foo: 'bar', num: 1 };
const obj2 = { foo: 'baz', num: 1 };

// Get raw diff result
const diffResult = diff(obj1, obj2);
console.log(diffResult);
// Output: { foo: { __old: 'bar', __new: 'baz' } }

// Get colorized string output
const diffOutput = diffString(obj1, obj2);
console.log(diffOutput);
// Output:
//  {
// -  foo: "bar"
// +  foo: "baz"
//  }

// Array comparison with fuzzy matching
const arr1 = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];
const arr2 = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Robert' }];

console.log(diffString(arr1, arr2));

Command Line Usage

# Compare two JSON files
json-diff file1.json file2.json

# With options
json-diff --full --color file1.json file2.json
json-diff --raw-json --keys-only file1.json file2.json

Capabilities

Core Comparison

diff

Compares two JSON objects and returns the structural differences.

/**
 * Compare two JSON objects and return structural differences
 * @param {any} obj1 - First object to compare
 * @param {any} obj2 - Second object to compare
 * @param {DiffOptions} options - Configuration options
 * @returns {any|undefined} Difference object or undefined if objects are equal
 */
function diff(obj1, obj2, options = {});

interface DiffOptions {
  /** Array of keys to always include in output even if unchanged */
  outputKeys?: string[];
  /** Array of keys to exclude from comparison */
  excludeKeys?: string[];
  /** Include equal sections of the document, not just deltas */
  full?: boolean;
  /** Compare only the keys, ignore the differences in values */
  keysOnly?: boolean;
  /** Include unchanged values in output instead of omitting them */
  keepUnchangedValues?: boolean;
  /** Output only the updated and new key/value pairs */
  outputNewOnly?: boolean;
  /** Sort primitive values in arrays before comparing */
  sort?: boolean;
  /** Round floating point numbers to specified decimal places before comparison */
  precision?: number;
}

Examples:

// Basic comparison
diff({ a: 1, b: 2 }, { a: 1, b: 3 });
// Returns: { b: { __old: 2, __new: 3 } }

// Full mode - includes unchanged values
diff({ a: 1, b: 2 }, { a: 1, b: 3 }, { full: true });
// Returns: { a: 1, b: { __old: 2, __new: 3 } }

// Keys only mode
diff({ a: 1, b: 2 }, { a: 1, b: 3 }, { keysOnly: true });
// Returns: undefined (same keys)

// Exclude specific keys
diff({ a: 1, b: 2, c: 3 }, { a: 1, b: 3, c: 4 }, { excludeKeys: ['c'] });
// Returns: { b: { __old: 2, __new: 3 } }

// Always output certain keys
diff({ a: 1, b: 2 }, { a: 1, b: 2 }, { outputKeys: ['a'] });
// Returns: { a: 1 }

// Precision rounding
diff({ pi: 3.14159 }, { pi: 3.14158 }, { precision: 3 });
// Returns: undefined (rounded values are equal)

diffString

Compares two JSON objects and returns a colorized string representation of the differences.

/**
 * Compare two JSON objects and return colorized string output
 * @param {any} obj1 - First object to compare
 * @param {any} obj2 - Second object to compare
 * @param {DiffStringOptions} options - Display and comparison options
 * @returns {string} Formatted, colorized string representation of differences
 */
function diffString(obj1, obj2, options = {});

interface DiffStringOptions extends DiffOptions {
  /** Enable/disable colored output (default: true) */
  color?: boolean;
  /** Custom color theme object */
  theme?: ColorTheme;
  /** Maximum number of elisions to show before collapsing them */
  maxElisions?: number;
}

interface ColorTheme {
  ' '?: (text: string) => string;  // Unchanged content (default: identity function)
  '+'?: (text: string) => string;  // Added content (default: green)
  '-'?: (text: string) => string;  // Removed content (default: red)
}

Examples:

// Colorized output (default)
diffString({ foo: 'bar' }, { foo: 'baz' });

// No colors
diffString({ foo: 'bar' }, { foo: 'baz' }, { color: false });

// Custom max elisions (default: Infinity)
diffString(largeArray1, largeArray2, { maxElisions: 3 });
// If more than 3 consecutive unchanged items, shows "... (N entries)" instead of individual "..."

// Full mode with no elisions limit
diffString(obj1, obj2, { full: true, maxElisions: Infinity });

Output Formatting

colorize

Converts a diff result object into a formatted, colorized string.

/**
 * Convert diff result to colorized string output
 * @param {any} diff - Diff result object from diff() function
 * @param {ColorizeOptions} options - Display options
 * @returns {string} Formatted, colorized string
 */
function colorize(diff, options = {});

interface ColorizeOptions {
  /** Enable/disable colored output (default: true) */
  color?: boolean;
  /** Custom color theme object */
  theme?: ColorTheme;
  /** Maximum number of elisions to show before collapsing them */
  maxElisions?: number;
}

Example:

const diffResult = diff({ foo: 'bar' }, { foo: 'baz' });
const colorized = colorize(diffResult, { color: true });
console.log(colorized);

colorizeToCallback

Converts a diff result object to colorized output using a callback function for each line.

/**
 * Convert diff result to colorized output using callback
 * @param {any} diff - Diff result object
 * @param {ColorizeOptions} options - Display options
 * @param {ColorizeCallback} output - Callback function to handle output lines
 * @returns {void}
 */
function colorizeToCallback(diff, options, output);

type ColorizeCallback = (color: string, line: string) => void;

Example:

const lines = [];
const diffResult = diff({ foo: 'bar' }, { foo: 'baz' });

colorizeToCallback(diffResult, { color: false }, (color, line) => {
  lines.push(`${color}${line}`);
});

console.log(lines.join('\n'));

colorizeToArray

Converts a diff result object to an array of colorized strings (available directly from colorize module).

/**
 * Convert diff result to array of colorized lines
 * @param {any} diff - Diff result object from diff() function
 * @param {ColorizeOptions} options - Display options (optional)
 * @returns {string[]} Array of formatted, colorized strings
 */
function colorizeToArray(diff, options = {});

Note: This function is exported from json-diff/lib/colorize but not from the main module.

Example:

const { colorizeToArray } = require('json-diff/lib/colorize');
const diffResult = diff({ foo: 'bar' }, { foo: 'baz' });
const lines = colorizeToArray(diffResult, { color: false });
console.log(lines);
// Output: [' {', '-  foo: "bar"', '+  foo: "baz"', ' }']

CLI Interface

The json-diff command provides a command-line interface for comparing JSON files.

# Usage
json-diff [options] <first.json> <second.json>

# Arguments:
# <first.json>                     Old file (required)
# <second.json>                    New file (required)

# General Options:
# -v, --verbose                    Output progress info
# -C, --[no-]color                 Colored output (auto-detected from TTY)
# -j, --raw-json                   Display raw JSON encoding of the diff
# -f, --full                       Include equal sections of document, not just deltas
# --max-elisions COUNT             Max number of ...s to show in a row in "deltas" mode (before collapsing them)

# Filtering Options:
# -o, --output-keys KEYS           Always print comma-separated keys with their value, if they are part of an object with any diff
# -x, --exclude-keys KEYS          Exclude comma-separated keys from comparison on both files
# -n, --output-new-only            Output only updated and new key/value pairs (without marking them as such)

# Comparison Options:
# -s, --sort                       Sort primitive values in arrays before comparing
# -k, --keys-only                  Compare only the keys, ignore differences in values
# -K, --keep-unchanged-values      Instead of omitting values that are equal, output them as they are
# -p, --precision DECIMALS         Round all floating point numbers to this number of decimal places prior to comparison

# Exit Codes:
# 0                               No differences found
# 1                               Differences found

Examples:

# Basic comparison (colors auto-detected based on TTY)
json-diff a.json b.json

# Full output with explicit colors
json-diff --full --color a.json b.json

# Force no colors
json-diff --no-color a.json b.json

# Raw JSON output only
json-diff --raw-json a.json b.json

# Compare only structure, not values
json-diff --keys-only a.json b.json

# Exclude timestamps from comparison
json-diff --exclude-keys timestamp,updatedAt a.json b.json

# Always show id field even if unchanged (requires --full or changes in object)
json-diff --output-keys id a.json b.json

Output Format

Raw JSON Mode

When using the diff() function or --raw-json CLI flag:

Object Changes

  • Scalar value changes: { "key": { "__old": oldValue, "__new": newValue } }
  • Deleted keys: { "key__deleted": deletedValue }
  • Added keys: { "key__added": newValue }

Array Changes

  • Array elements: Transformed into 2-tuples [operation, value]
  • Operations: " " (unchanged), "+" (added), "-" (deleted), "~" (modified)
  • Unchanged elements in delta mode: [" "] (value omitted)
  • Unchanged elements in full mode: [" ", value]

Examples:

// Object with changed value
diff({ name: "John" }, { name: "Jane" });
// Result: { name: { __old: "John", __new: "Jane" } }

// Object with added key
diff({ a: 1 }, { a: 1, b: 2 });
// Result: { b__added: 2 }

// Array with changes
diff([1, 2, 3], [1, 4, 3]);
// Result: [[" "], ["-", 2], ["+", 4], [" "]]

Colorized String Mode

When using diffString() or CLI without --raw-json:

  • Green (+): Added elements
  • Red (-): Deleted elements
  • White: Unchanged elements (in full mode)
  • Elisions: Consecutive unchanged elements shown as ...

Advanced Features

Fuzzy Array Matching

JSON Diff uses intelligent fuzzy matching for arrays containing objects. When array elements are modified, it attempts to match similar objects rather than treating them as separate additions and deletions.

const before = [
  { id: 1, name: "Alice", role: "admin" },
  { id: 2, name: "Bob", role: "user" }
];

const after = [
  { id: 1, name: "Alice", role: "admin" },
  { id: 2, name: "Robert", role: "user" }  // name changed
];

// Shows modification rather than delete + add
diffString(before, after);
// Output shows Bob -> Robert change, not full object replacement

Precision Handling

For floating-point comparisons, use the precision option to avoid issues with floating-point representation:

diff(
  { measurement: 3.14159265359 },
  { measurement: 3.14159265358 },
  { precision: 5 }
);
// Returns: undefined (equal when rounded to 5 decimal places)

Error Handling

The library throws errors for:

  • Invalid JSON input (when reading files in CLI)
  • Internal consistency errors during array processing
  • Invalid CLI arguments

All functions handle null, undefined, and various JavaScript types gracefully.

Types Reference

// Core diff result types
type DiffResult = any | undefined;

// Array diff tuple format
type ArrayDiffTuple = [' ' | '+' | '-' | '~', any] | [' '];

// Object change format for scalar values
interface ScalarChange {
  __old: any;
  __new: any;
}

// Object key change formats
interface ObjectKeyChange {
  [key: `${string}__added`]: any;    // Added keys
  [key: `${string}__deleted`]: any;  // Deleted keys  
}

// Color operations used in diff output
type ColorOperation = ' ' | '+' | '-' | '~';

// CLI exit codes
const CLI_EXIT_CODES = {
  NO_DIFFERENCES: 0,      // Files are identical
  DIFFERENCES_FOUND: 1    // Files have differences
};

// Extended types recognized by json-diff
type ExtendedType = 'null' | 'array' | 'date' | 'object' | 'string' | 'number' | 'boolean' | 'undefined';