Merge Deep
merge-deep is a JavaScript utility designed to recursively merge the properties of one or more source objects into a target object. It is currently at stable version 3.0.3, maintaining a mature and relatively stable codebase. The library's core functionality is to perform a deep merge, meaning it traverses nested objects and combines their properties rather than simply overwriting them, which is a common behavior in shallow merge operations. This ensures a comprehensive union of object structures. It draws its implementation foundation from the `mout` library's merge utility. While a specific release cadence isn't explicitly defined, the project typically receives updates for maintenance or minor enhancements. A key differentiator is its commitment to a pure function approach, aiming to return a new merged object without directly mutating the input objects, providing a predictable and side-effect-free way to combine complex configurations or data structures.
Common errors
-
ReferenceError: require is not defined
cause Attempting to use `require()` in an ES Module context (e.g., a file with `.mjs` extension or a project with `'type': 'module'` in `package.json`).fixEither revert your project or file to CommonJS (`.cjs` file extension or remove `'type': 'module'`) or use dynamic import `import('merge-deep').then(module => module.default || module);` if your environment supports it. -
TypeError: merge-deep is not a function
cause This error often occurs when attempting to use a named ESM import (`import { merge } from 'merge-deep';`) when the module exports a default function via CommonJS (`module.exports = function merge(...)`).fixChange the import statement to `import merge from 'merge-deep';` if your environment supports default ESM imports from CJS modules, or preferably `const merge = require('merge-deep');` in a CommonJS context. -
RangeError: Maximum call stack size exceeded
cause Merging objects that contain circular references (an object property directly or indirectly references itself), causing the recursive merge function to enter an infinite loop.fixInspect the objects for circular references and remove them, or preprocess the objects using a utility that can detect and handle or flatten circular structures before merging.
Warnings
- gotcha When merging objects containing non-plain objects such as `Date` objects, `RegExp` instances, or custom class instances, `merge-deep` will typically clone them as plain objects, losing their original type or prototype chain. This is a common behavior in many deep merge utilities but can lead to loss of functionality for complex objects.
- gotcha The library performs a deep merge, but arrays are typically overwritten rather than concatenated if a source object provides an array value for an existing array property on the target. This can lead to unexpected data loss if array concatenation is expected.
- gotcha This utility does not explicitly handle circular references within objects. Merging objects with circular structures may lead to an infinite loop and a `RangeError: Maximum call stack size exceeded`.
- breaking As `merge-deep` is a CommonJS-first module, attempting to use ES Module `import` syntax directly in an ESM environment without proper transpilation or bundler configuration can lead to module resolution errors or `TypeError: merge-deep is not a function`.
Install
-
npm install merge-deep -
yarn add merge-deep -
pnpm add merge-deep
Imports
- merge
import { merge } from 'merge-deep';const merge = require('merge-deep'); - merge (ESM)
const merge = require('merge-deep');import merge from 'merge-deep';
Quickstart
const merge = require('merge-deep');
const obj1 = {
a: {
b: {
c: 'c1',
d: 'd1'
},
x: 1
}
};
const obj2 = {
a: {
b: {
e: 'e2',
f: 'f2'
},
y: 2
},
z: 3
};
// Basic deep merge of two objects
const merged = merge(obj1, obj2);
console.log('Merged two objects:', merged);
// Expected: { a: { b: { c: 'c1', d: 'd1', e: 'e2', f: 'f2' }, x: 1, y: 2 }, z: 3 }
// Demonstrate merging multiple objects into a new empty object
const obj3 = { a: { b: { g: 'g3' } } };
const mergedMany = merge({}, obj1, obj2, obj3);
console.log('Merged multiple objects:', mergedMany);
// Expected to deeply merge properties from obj1, obj2, obj3 into a new empty object.