Fast Equality Comparison Utility
fast-equals is a high-performance utility library designed for deep and shallow equality comparisons between JavaScript values, offering significant speed advantages and a small bundle size (~2KB minified and gzipped). Currently stable at version 6.0.0, the library maintains a steady release cadence with minor updates for bug fixes and features, and major versions for breaking changes and significant enhancements. It differentiates itself by providing a comprehensive suite of equality methods (deep, shallow, SameValue, SameValueZero, strict, and circular-aware comparisons), built-in support for a wide array of JavaScript types including Objects, Arrays, TypedArrays, Dates, RegExps, Maps, Sets, Promises, and custom class instances. Furthermore, it offers robust customization options through `createCustomEqual`, allowing developers to define comparison logic for specific types or use cases, all without any external dependencies.
Common errors
-
Error: Cannot find module 'fast-equals/dist/umd/index.js'
cause Attempting to import from the UMD build path after upgrading to `fast-equals` v6.0.0, which removed UMD support.fixUpdate your import statements or bundler configuration to use the ESM (`import ... from 'fast-equals'`) or CommonJS (`require('fast-equals')`) builds. The default package entry point should resolve correctly. -
TypeError: (0 , fast_equals_1.deepEqual) is not a function
cause This error typically occurs when an ESM named export is incorrectly imported or accessed, often in environments with mixed module systems (CommonJS trying to import ESM, or vice-versa) or incorrect bundler configurations.fixEnsure you are using `import { deepEqual } from 'fast-equals';` for ESM environments and `const { deepEqual } = require('fast-equals');` for CommonJS environments. Verify your `tsconfig.json` and bundler settings (`moduleResolution`, `module`) are correctly configured for your target environment. -
TS2305: Module '"fast-equals"' has no exported member 'Equals'
cause As part of the v6.0.0 cleanup, the package reduced exposed types. You are likely attempting to import a type that is no longer part of the public API.fixReview the official `fast-equals` documentation or source code for the current set of publicly exposed types. If a specific type is no longer available, consider if you truly need to import it, or if a more general type definition suffices.
Warnings
- breaking As of v6.0.0, `fast-equals` has dropped Universal Module Definition (UMD) support. Users relying on UMD bundles (e.g., via `<script>` tags in browsers or specific legacy bundler configurations) must update their import strategy to use either ESM or CommonJS builds.
- breaking Version 6.0.0 significantly reduced the number of directly exposed types and removed indirect methods from `equals.ts`. If you were previously importing specific internal types or methods directly from deep paths within the package, these imports will likely break.
- gotcha When comparing `Map` objects, `fast-equals` performs a deep equality comparison for both keys and values, deviating from the `SameValueZero` spec for key lookups. This means `Map` instances with structurally identical but referentially different complex keys will be considered equal, which may not align with native `Map` behavior for key access.
- deprecated The `equals.ts` indirect methods were removed in v6.0.0. While not broadly used, direct access to these internal mechanisms is no longer supported.
- gotcha The `strictEqual` method, introduced in v6.0.0, performs a JavaScript strict equality comparison (`===`) on its inputs. It is crucial to understand that `strictEqual` will return `false` for two distinct objects or arrays that have identical content, as it compares references, not deep structure. It is distinct from `deepEqual`.
Install
-
npm install fast-equals -
yarn add fast-equals -
pnpm add fast-equals
Imports
- deepEqual
const deepEqual = require('fast-equals');import { deepEqual } from 'fast-equals'; - createCustomEqual
import * as FastEquals from 'fast-equals'; FastEquals.createCustomEqual;
import { createCustomEqual } from 'fast-equals'; - shallowEqual
import shallowEqual from 'fast-equals/dist/es/shallowEqual.mjs';
import { shallowEqual } from 'fast-equals';
Quickstart
import { deepEqual, shallowEqual, createCustomEqual, strictEqual } from 'fast-equals';
const objA = { a: 1, b: { c: 2 }, d: [3, 4] };
const objB = { a: 1, b: { c: 2 }, d: [3, 4] };
const objC = { a: 1, b: { c: 99 }, d: [3, 4] };
const arr1 = [1, { foo: 'bar' }, new Date('2023-01-01')];
const arr2 = [1, { foo: 'bar' }, new Date('2023-01-01')];
const arr3 = [1, { foo: 'baz' }, new Date('2023-01-01')];
console.log('Deep equality (objects):', deepEqual(objA, objB)); // true
console.log('Deep equality (objects with difference):', deepEqual(objA, objC)); // false
console.log('Shallow equality (objects):', shallowEqual(objA, objB)); // false (nested objects/arrays are different references)
console.log('Deep equality (arrays):', deepEqual(arr1, arr2)); // true
console.log('Deep equality (arrays with difference):', deepEqual(arr1, arr3)); // false
const customEqual = createCustomEqual({ createComparator: () => (a, b) => a === b || a.value === b.value });
console.log('Custom equality (simple values):', customEqual({ value: 1 }, { value: 1 })); // true
console.log('Strict equality (same value, different reference):', strictEqual([1], [1])); // false
console.log('Strict equality (same reference):', strictEqual(objA, objA)); // true