react-fast-compare

The fastest deep-equal comparison for React, purpose-built for React.memo and shouldComponentUpdate.

Library
npm
v3.2.2
1,665stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
47/100Fair
Development Activity0
Maintenance20
Community68
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
75/100Good
Architecture78
Code Quality85
Innovation58
Learning Curve80

react-fast-compare is a tiny, dependency-free deep-equality function that Formidable forked from fast-deep-equal and hardened for React. It compares any two values deeply, including nested objects, arrays, Maps, Sets, Dates, RegExps, and typed arrays, while adding guardrails for the circular references that React elements naturally contain.

Because it’s a single unified entry point with no configuration, it drops straight into React.memo’s comparator or a class component’s shouldComponentUpdate to skip unnecessary re-renders when props or state have not actually changed. At under 660 bytes minified and gzipped, it adds negligible weight while matching fast-deep-equal’s raw comparison speed.

What You Get

  • A single isEqual(a, b) function with one unified entry point for every environment (ES5-compatible, works in Node 0.10+ and IE9+)
  • Deep structural comparison of objects, arrays, Maps, Sets, Dates, RegExps, and typed arrays
  • Safe handling of circular references in React and Preact elements (_owner, __v, __o) without infinite recursion
  • A try/catch guardrail that falls back to false with a console warning instead of crashing on unexpected circular refs
  • Bundled TypeScript typings (index.d.ts) with a type-predicate signature (a is B)

Common Use Cases

  • Comparator function passed to React.memo(Component, isEqual) to prevent re-renders on deeply-equal props
  • shouldComponentUpdate implementations in class components that need a deep prop/state comparison
  • General-purpose deep equality checks in application or library code outside of React, such as memoization caches or test assertions
  • Drop-in replacement for fast-deep-equal in codebases that also render React elements and need circular-safe comparisons

Under The Hood

Architecture The entire library is a single CommonJS module (index.js) exporting one function, isEqual, which wraps an inner recursive equal(a, b) in a try/catch. equal is a fork of fast-deep-equal’s ES6 implementation, extended with explicit branches for Map, Set, and typed-array (ArrayBuffer.isView) comparisons, plus a React/Preact-specific loop that skips known circular-reference keys (_owner, __v, __o) when iterating an object’s own keys. There is no class hierarchy, no configuration surface, and no plugin system — correctness for React’s circular ownership graphs is achieved by special-casing a handful of well-known property names rather than by generalized cycle detection, which keeps the hot path branch-light and fast.

Tech Stack Runtime code has zero dependencies and targets ES5 for broad compatibility (Node 0.10+, IE9+), with a bundled index.d.ts for TypeScript consumers. The development toolchain is heavier: Babel and core-js for transpilation checks, Karma (Chrome/Firefox/Safari launchers) plus jsdom/jsdom-global for browser-environment tests, Mocha and nyc for Node tests and coverage, ESLint with eslint-plugin-react for linting, terser for the bundle-size (compress) script, and changesets for release/versioning. CI runs the full matrix (Node 18 on Ubuntu and Windows) via GitHub Actions and reports to Codecov.

Code Quality Testing is thorough for the library’s scope: test/node covers basic and advanced equality cases via Mocha with coverage tracked by nyc, test/browser re-runs the same suite through Karma across real browser engines, and test/typescript type-checks sample usage against the shipped .d.ts file with tsc. The single yarn test script chains ESLint, the TypeScript checks, Node tests with coverage, and the browser suite through builder concurrent, so a broken lint rule or type signature fails CI the same as a broken assertion. The source itself is heavily commented, marking exactly which lines are inherited from fast-deep-equal versus added for React, which makes the intentionally terse, performance-oriented code easy to audit despite minimal abstraction.

What Makes It Unique Its value isn’t algorithmic novelty — the comparison logic is explicitly inherited from fast-deep-equal and the README says as much — but the small, specific delta it adds: guardrails against the exact circular-reference shapes React and Preact elements produce, plus a single unified entry point instead of fast-deep-equal’s multiple per-environment exports. That narrow, well-scoped adaptation is what makes it safe to hand directly to React.memo or shouldComponentUpdate where the unmodified original library would risk a stack overflow on any props containing React elements.

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