Blogchevron_rightJSON Tools
JSON Tools

JSON Deep Equality in JavaScript: Comparing Objects Correctly

JavaScript has no built-in deep equality operator. Comparing JSON objects correctly requires understanding why === fails and which alternatives work.

April 18, 2026·7 min read

Why === Does Not Work for JSON Objects

The === operator compares objects by reference, not by value. Two separate objects with identical properties are not === because they are different objects in memory: { a: 1 } === { a: 1 } evaluates to false. This catches many developers off guard when writing tests or comparison logic.

For primitive JSON values (strings, numbers, booleans, null), === works correctly. The comparison problem is specific to objects and arrays, which are reference types in JavaScript. Deep equality for these types requires recursive value comparison.

The JSON.stringify Approach

A common workaround is JSON.stringify(obj1) === JSON.stringify(obj2). This works for simple cases but has subtle failure modes: key order affects the string comparison ({"a":1,"b":2} !== {"b":2,"a":1} even though they are logically equal), and non-serializable values (undefined, functions) produce identical "" for different objects.

The key-order problem can be mitigated by sorting keys before stringifying. A recursive sort function or jq's -S flag produces sorted-key JSON. But this still fails for objects with non-serializable values. For robust equality, use a dedicated deep equality library.

Reliable Deep Equality Methods

For Node.js: const { deepStrictEqual } = require("assert"); deepStrictEqual(obj1, obj2) throws AssertionError if they differ, or returns undefined if equal. This handles key order correctly (objects are equal regardless of key order) and distinguishes undefined from missing keys.

Lodash's _.isEqual(obj1, obj2) is the most widely used deep equality function in JavaScript. It handles objects, arrays, Dates, RegExp, Maps, Sets, and circular references correctly. Import just the isEqual function for minimal bundle impact: import isEqual from "lodash/isEqual".

Using a JSON Compare Tool for Development

For development-time comparison (understanding what changed between two API responses, debugging test failures), an online JSON compare tool is faster than writing comparison code. Paste the two JSON objects, get an instant diff highlighting all differences, and understand what changed.

JSON compare tools are particularly valuable when the objects are large (hundreds of fields) or deeply nested, where reading both side by side is impractical. The diff output reduces a complex comparison to a list of specific field differences.

Try JSON Compare Free Online

No sign-up required. 100% client-side — your data never leaves your browser.

Open JSON Comparearrow_forward

Frequently Asked Questions

Does structuredClone help with JSON deep equality?

structuredClone creates a deep copy but does not help with equality comparison — two structuredClone copies are still different objects. Use assert.deepStrictEqual or lodash isEqual for comparison.

Is JSON.stringify comparison reliable for test assertions?

It is fragile due to key order sensitivity and non-serializable value handling. Use a proper testing library assertion like Jest's toEqual, which performs deep equality without these issues.

Can I compare JSON objects in TypeScript with type safety?

TypeScript adds type checking to comparisons but does not change the runtime equality semantics. Use lodash isEqual with TypeScript generics or a validation library like zod for both type-safe parsing and comparison.

JSON Deep Equality in JavaScript: Comparing Objects