# dequal Deep Equality for Compact JavaScript Bundles

> dequal is a small JavaScript utility for comparing values by structure rather than identity. Its standard build supports modern collection and binary-data types, while the lite build trades those capabilities for a smaller gzip size.

**lukeed/dequal** — A tiny (304B to 489B) utility to check for deep equality

- Repository: https://github.com/lukeed/dequal
- Stars: 1,469 · Forks: 39
- Language: JavaScript
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/lukeed-dequal

## What dequal Compares

dequal addresses a specific JavaScript problem: deciding whether two values contain equivalent structures without writing a recursive comparison function for each call site. It is intended for developers comparing configuration objects, parsed data, state snapshots, arrays, and other values where object identity is not the relevant criterion. The API consists of `dequal(foo, bar)`, which returns a Boolean indicating whether the two arguments are deeply equal.

The comparison rules are explicit. Object key order does not affect the result, so `{ a: 1, b: 2 }` and `{ b: 2, a: 1 }` are treated as equal when their values match. Array order does matter because array positions represent different values. Maps and Sets use value equality rather than reference equality, including value equality for Map keys. The README also lists support for `Function`, `RegExp`, `Date`, `Set`, `Map`, `TypedArray`, `DataView`, `ArrayBuffer`, `null`, `undefined`, and `NaN`.

This makes dequal more specific than a simple identity check, while remaining narrower than a general-purpose equality policy. It does not document options for custom comparers, circular-reference handling, error comparison, asymmetric matching, or path-level diagnostics. The documented contract is therefore a compact structural comparison rather than a configurable validation framework.

## Full and Lite Comparison Modes

dequal ships two entry points with different compatibility and size targets. The main `dequal` build is documented as 489 bytes gzip and is available as CommonJS, ES Module, and UMD. The `dequal/lite` build is documented as 304 bytes gzip and is available as CommonJS and ES Module. The package metadata maps these modes to `src/index.js` and `src/lite.js`, then publishes built files through the package exports map.

The type table is the important adoption constraint. The full `dequal` build includes Numbers, Strings, Dates, RegExp expressions, objects, arrays, classes, Sets, Maps, ArrayBuffer, TypedArrays, and DataView, but the table does not mark it as supporting IE9. The lite build is marked for IE9 and later, but it does not include Set, Map, ArrayBuffer, TypedArray, or DataView support. It still supports primitive values, Dates, RegExp expressions, objects, arrays, and classes according to the table.

A project with a size budget may prefer `dequal/lite`, but that choice can remove support for data structures that are central to the application. The stated gzip figures show a size difference between the builds. That difference is concrete, although the actual application impact depends on the bundler and the rest of the package.

## Recursive Equality Semantics

The README states that complex values, including objects, arrays, Sets, and Maps, are traversed recursively. That design allows nested values such as objects inside arrays and objects inside objects to participate in the same comparison without a separate equality routine for each container.

The examples distinguish the important cases. `dequal({}, {})` returns `true`, while `dequal(1, '1')` and `dequal(null, undefined)` return `false`. Nested arrays and objects compare by their contents. A regular expression example shows that flags and source are relevant, since `/foo/i` and `/bar/g` return `false`. `NaN` compares as equal to `NaN`, which differs from the ordinary JavaScript result of `NaN === NaN` and is useful when comparing computed result data.

Map and Set handling has a specific consequence. A Map can match another Map even when corresponding keys are different object references, provided the keys are equal under dequal's rules. This is different from libraries that compare Map entries by identity. Conversely, the README does not define a way to pass a domain-specific comparator for dates with different time zones, class instances with additional state, or objects that need a partial match. Applications with those requirements should not treat dequal's Boolean result as a complete replacement for a validation or domain comparison layer.

## Installing and Using dequal

The README gives one installation command. It installs `dequal` and saves it to the package dependencies in the current npm project.

```bash
$ npm install --save dequal
```

For an ES module application, import the named `dequal` export and compare two values. The following call checks two arrays containing nested objects and returns `true` because their structures match.

```js
import { dequal } from 'dequal';

dequal(
  [{ a:1 }, [{ b:{ c:[1] } }]],
  [{ a:1 }, [{ b:{ c:[1] } }]]
); //=> true
```

The full package entry point is the default import target for normal builds. The package metadata declares Node `>=6` support in `package.json`. Its exports map provides separate `import` and `require` files for both the root and lite entry points, and the package includes TypeScript declarations through `index.d.ts`.

## Where dequal Is the Wrong Tool

The first boundary is compatibility. The lite build is the wrong choice when application data includes `Set`, `Map`, `ArrayBuffer`, `TypedArray`, or `DataView`, because the README marks those types as unsupported for that mode. The table marks the lite mode for IE9 and later but does not mark the full mode for IE9; projects needing the full collection and binary-data coverage should select `dequal` rather than `dequal/lite`.

The second boundary is comparison policy. dequal returns one Boolean and does not document configurable comparison functions. It is therefore unsuitable for partial equality, tolerant numeric comparisons, custom class semantics, or rules that distinguish missing properties from properties explicitly set to `undefined`. The documentation also does not state how circular references are handled. Code that receives self-referential objects should verify this behavior in the target application before relying on it.

Finally, the package's compact scope does not replace native tools when the application needs richer error reporting. `assert.deepStrictEqual` and `util.isDeepStrictEqual` are included in the README's benchmark candidates. dequal is more attractive when bundle size and a minimal recursive API matter, but its small API returns only a Boolean rather than a detailed explanation.

## License, Releases, and Maintenance Signals

dequal is published under the MIT license by Luke Edwards. The package metadata identifies version `2.0.3` and points to the `lukeed/dequal` repository. The repository is not archived, and its last push was on 2026-04-10. The release list shows `v2.0.3` dated 2022-07-11, after `v2.0.2` from 2020-08-19 and `v2.0.1` from 2020-08-17.

That information gives users two separate signals. The repository remains available and has a recent recorded push, but the latest listed package release is from 2022. The README does not document a release schedule, migration policy, or compatibility matrix beyond the stated engine and browser coverage. Before changing an existing dependency, inspect the current package version and compare the published `exports`, type declarations, and build files with the integration being used.

The MIT license is permissive in general terms, but it does not answer project-specific questions about redistribution, notices, or third-party dependencies. Users should review the repository license file and their own distribution requirements rather than relying only on the package metadata.

## dequal Compared with Native Node Equality

Node's built-in equality facilities and dequal solve overlapping problems with different priorities. The README benchmark lists `assert.deepStrictEqual` and `util.isDeepStrictEqual` alongside dequal, while dequal's documented API returns a Boolean.

dequal instead targets application code that needs to decide whether arbitrary JavaScript values are equal and cares about package size. Its documented full build handles a broad set of JavaScript types, and its Map and Set rules use value equality. The lite build is a separate tradeoff for bundles that can exclude newer collection and binary-data types. The README's benchmark section lists these tools together, but the repository does not define dequal as a drop-in replacement for Node's assertion semantics.

The practical distinction is therefore API intent and diagnostic behavior. Use dequal for a compact predicate inside application logic. Use Node's native facilities when the surrounding test or runtime workflow depends on their assertion behavior or diagnostics. For browser bundles, confirm the selected dequal entry point against the exact types present in the data.

## Conclusion

Developers building compact browser or Node.js code should consider dequal when structural equality is enough, especially if they need Map and Set support. Projects requiring native compatibility guarantees, custom comparison rules, or browser support below IE9 should verify the chosen build against those constraints before adoption. For dequal v2.0.3, the first check is whether `dequal/lite` covers the types in the application or whether the full `dequal` entry point is required.

## FAQ

### How do I install dequal?

Run `npm install --save dequal` in the npm project. The README documents this as the installation command.

### What is the difference between dequal and dequal/lite?

The main `dequal` build is documented as 489 bytes gzip and supports Set, Map, ArrayBuffer, TypedArray, and DataView values. `dequal/lite` is documented as 304 bytes gzip and marks those types unsupported.

### Does dequal compare object keys and array values by order?

Object key order does not matter, while array value order does. The README also states that Set and Map values, including Map keys, use value equality.

### Does dequal support Node.js and TypeScript?

The package metadata declares Node `>=6` and includes `index.d.ts` as its types entry. The package exports map provides both `import` and `require` files for the root and lite entry points.

### Can dequal compare circular objects?

The README does not document circular-reference behavior. The API documentation only states that complex values are traversed recursively, so circular inputs should not be assumed to be supported without separate verification.

## Sources

- [Issues](https://github.com/lukeed/dequal/issues)
- [License: MIT](https://github.com/lukeed/dequal/blob/master/LICENSE)
- [lukeed/dequal on GitHub](https://github.com/lukeed/dequal)
- [README](https://github.com/lukeed/dequal/blob/master/README.md)
- [Releases](https://github.com/lukeed/dequal/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/lukeed-dequal
