This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This repository contains loose-deep-equal, a fast deep equality comparison library that treats missing properties as equal to undefined. It's based on fast-deep-equal but modified to support loose equality semantics, making it ideal for comparing API responses, configuration objects, and other scenarios where undefined and missing properties should be considered equivalent.
# Run all tests (includes our tests + fast-deep-equal test suite)
npm test
# Run specific test files
node test/test.js # Our custom tests
node test/test-fast-deep-equal-suite.js # fast-deep-equal test suite
node test/test-commonjs.js # CommonJS import test
node test/test-esm.mjs # ESM import test# Run main benchmarks
npm run benchmark
# Run specific benchmarks
node benchmark/benchmark-with-undefined.js # Detailed undefined equality benchmarks
node benchmark/benchmark-large-json.js # Large JSON file test (requires /tmp/app.json)
node benchmark/edge-cases.js # Edge case comparisons# Test specific edge cases
node test/test-undefined-equality.js # Basic undefined equality tests
node test/test-malicious-objects.js # Security tests
node test/test-comprehensive-edge-cases.js # All edge cases
node test/test-undefined-specific.js # Undefined-specific behaviorsloose-deep-equal/
├── src/ # Main source code
│ ├── index.js # CommonJS entry point
│ ├── index.mjs # ESM wrapper
│ └── index.d.ts # TypeScript definitions
├── test/ # All test files
│ ├── test.js # Core functionality tests
│ ├── test-fast-deep-equal-suite.js # fast-deep-equal test adapter
│ ├── fast-deep-equal-tests.js # Original test data
│ ├── fast-deep-equal-es6tests.js # ES6 test data
│ ├── test-commonjs.js # CommonJS import test
│ ├── test-esm.mjs # ESM import test
│ ├── run-all.js # Test runner
│ └── [various edge case test files]
├── benchmark/ # Benchmark files
│ ├── index.js # Main benchmark suite
│ ├── benchmark-with-undefined.js
│ ├── benchmark-large-json.js
│ └── edge-cases.js
├── package.json # Package configuration
├── README.md # User documentation
├── CLAUDE.md # AI assistant guidance
├── LICENSE # MIT license
└── .npmignore # NPM publish configuration
The main implementation with key features:
- Fast path: When objects have same number of keys, uses original fast-deep-equal algorithm
- Slow path: When key counts differ, uses optimized double-loop to check all properties
- ES6 Support: Handles Maps, Sets, TypedArrays, and BigInt
- Safety: Uses
Object.prototype.hasOwnProperty.call()to avoid prototype pollution
src/index.js- CommonJS entry pointsrc/index.mjs- ESM wrapper providing default and named exportssrc/index.d.ts- TypeScript definitions for both import styles
test/test.js- Core functionality teststest/test-fast-deep-equal-suite.js- Adapter for running fast-deep-equal's test suitetest/fast-deep-equal-tests.js&test/fast-deep-equal-es6tests.js- Original test data from fast-deep-equal
-
Loose Equality Logic: The core difference is in object comparison - when objects have different numbers of keys, the implementation:
- Iterates through all keys from object A, treating missing keys in B as undefined
- Iterates through keys from B that aren't in A, comparing them against undefined
- This avoids creating intermediate Sets while maintaining correctness
-
Performance Optimizations:
- Early constructor check to avoid comparing different types
- Special handling for null prototype objects
- Native for-of loops for ES6 collections
- Backward iteration for arrays (cache-friendly)
-
Expected Test Failures: Only 2 tests from fast-deep-equal's suite fail as expected:
object with extra undefined properties are not equal #1object with extra undefined properties are not equal #2These failures are correct behavior for loose equality.
The package supports both CommonJS and ESM:
"main": CommonJS entry"module": ESM entry"exports": Conditional exports for Node.js"sideEffects": false: Enables tree-shaking"engines": Requires Node.js >=16.0.0
Based on benchmarks:
- Simple equal objects: ~72% of fast-deep-equal speed
- Nested objects: ~85% of fast-deep-equal speed
- Large objects (100+ properties): ~96% of fast-deep-equal speed
- Objects with undefined properties: ~33% speed (due to checking all keys)
- Still 3-6x faster than lodash.isEqual in all cases