← Back to Blog
Code Snippets August 13, 2026

JavaScript: Deep Object Comparison — Find Exactly What Changed

💻 Code Snippet — Aug 13, 2026

JavaScript: Deep Object Comparison — Find Exactly What Changed

JSON.stringify(a) === JSON.stringify(b) fails on NaN, undefined, Date, key order, and gives no path info. This returns the exact paths of differences:

// Find what changed between two objects
const diffs = deepDiff(oldObj, newObj);
// [{ path: 'root.email', type: 'changed',
//    oldValue: 'a@old.com', newValue: 'a@new.com' },
//  { path: 'root.settings.lang', type: 'added',
//    newValue: 'en' }]


The pattern — deepDiff(obj1, obj2) returns:
  • type: 'changed' — value differs at that path

  • type: 'added' — key exists in obj2 but not obj1

  • type: 'removed' — key exists in obj1 but not obj2

  • path — bracket notation: root.user.settings.theme or root.tags[2]


Handles edge cases that JSON.stringify misses:
  • NaN === NaN ✓ (not false)

  • null !== undefined ✓ (they're different)

  • Date objects compared by .getTime()

  • Key order invariant: {a:1,b:2} == {b:2,a:1}

  • Circular references — won't hang (WeakSet guard) ✓

  • Arrays — compared by index, detects added/removed elements ✓


Zero dependencies — vanilla JS, Node.js & browsers. Feed the paths to lodash.set() or use them for targeted React re-renders.