json-diff

A Node.js CLI and library for structural JSON diffing, with fuzzy matching for changed array elements and colorized terminal output.

Library
npm
v1.0.6
1,202stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
40/100Fair
Development Activity0
Maintenance0
Community72
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
61/100Good
Architecture70
Code Quality50
Innovation65
Learning Curve60

json-diff is a Node.js library and command-line tool that computes a structural diff between two JSON documents. Rather than treating JSON as flat text, it walks the object/array tree and reports exactly which keys were added, removed, or changed in value, including fuzzy matching of array elements so a modified object inside an array is recognized as “changed” rather than shown as a confusing delete-then-insert pair.

It ships both as a global CLI (json-diff a.json b.json) with colorized terminal output, and as an importable module (diff, diffString) for use inside test suites, build scripts, or other tooling that needs to compare JSON programmatically.

What You Get

  • A CLI binary (json-diff) for comparing two JSON files directly from the terminal with colorized output
  • Importable diff() and diffString() functions for programmatic use in Node.js scripts and test suites
  • Fuzzy matching for array elements so reordered or partially-changed objects inside arrays are matched intelligently instead of showing as noisy add/remove pairs
  • Configurable output modes: full-tree output, keys-only comparison, sorted array comparison, floating-point precision rounding, and key inclusion/exclusion filters

Common Use Cases

  • Comparing API response snapshots in test suites to assert only the intended fields changed
  • Diffing configuration or manifest files in CI to catch unintended structural changes
  • Reviewing structural changes between two versions of a JSON data export or fixture
  • Debugging why two seemingly similar JSON payloads produce different application behavior

Under The Hood

Architecture The library is a small, script-shaped codebase with clear single-responsibility modules: lib/index.js holds a JsonDiff class implementing the recursive diff()/objectDiff()/arrayDiff() algorithm, lib/colorize.js renders a diff result into ANSI-colored strings, lib/cli.js parses argv (via dreamopt) and wires file/stdin input into the diff-then-colorize pipeline, and lib/util.js provides small type-detection and rounding helpers. Array diffing works by “scalarizing” non-scalar array elements into synthetic sentinel keys chosen via a best-match scoring pass (findMatchingObject), then running LCS-based sequence matching (from @ewoudenberg/difflib) over those synthetic sequences — letting a modified object retain its identity across a diff instead of appearing as a delete/insert pair. There’s no dependency injection or plugin system; the three surfaces (library API, CLI, colorize) are tightly coupled through the exact shape of diff()’s output.

Tech Stack Originally written in CoffeeScript (still preserved under old-coffee-lib/), the library has since been rewritten in plain ES6 JavaScript classes with no build step or bundler — it ships lib/*.js directly. Runtime dependencies are minimal: @ewoudenberg/difflib (a JS port of Python’s difflib for LCS sequence matching), colors for terminal styling, and dreamopt for declarative CLI option parsing. Dev tooling includes coffeescript (retained only to compile the legacy .coffee test files), eslint with eslint-config-standard, mocha for test running, and jscoverage for coverage reports. It’s distributed via npm as both a global CLI (bin/json-diff.js) and an importable module (main: lib/index.js).

Code Quality Tests live in test/*.coffee and are compiled with coffee -c test before being run with mocha — an unusual two-step pipeline that still depends on the legacy CoffeeScript toolchain even though the library itself is plain JS. The README documents extensive test coverage of diff/colorize edge cases across scalars, objects, and arrays under every option combination (sort, keysOnly, full, keepUnchangedValues). There’s no TypeScript or runtime type checking — values are duck-typed via typeof/instanceof checks in util.js. Error handling is minimal, limited to an internal invariant check thrown as a plain Error in arrayDiff; no CI workflow file was found in the shallow clone, and recent commit activity is low.

API Design The public API is deliberately minimal and low-friction: two functions, diff(a, b, options) and diffString(a, b, options), cover nearly every use case with zero setup beyond a single require. Its real differentiator is the fuzzy array-matching behavior described above, which produces meaningfully cleaner diffs for arrays of objects than a naive positional or stringify-based comparison would. The option set (sort, keysOnly, full, outputKeys, excludeKeys, precision, outputNewOnly) is documented in the README with runnable, copy-pasteable examples for both the CLI and the JS API.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search