deepmerge is a library for deep (recursive) merging of JavaScript objects. It creates new objects without modifying the original objects, providing a safe way to combine object data with customizable merge behavior for arrays and special object types.
npm install deepmergedist/cjs.js (CommonJS)const merge = require('deepmerge');For TypeScript projects:
import * as merge from 'deepmerge';Alternative TypeScript import syntax:
import merge = require('deepmerge');Note: deepmerge is a CommonJS module. The ESM entry point was removed due to a Webpack bug.
Accessing types in TypeScript:
import merge = require('deepmerge');
// Types are accessible via the merge namespace:
const options: merge.Options = { clone: true };
const arrayOptions: merge.ArrayMergeOptions = { /* ... */ };For browser usage without bundlers:
<script src="https://unpkg.com/deepmerge/dist/umd.js"></script>
<script>
const result = deepmerge({ a: 1 }, { b: 2 });
</script>const merge = require('deepmerge');
const x = {
foo: { bar: 3 },
array: [{
does: 'work',
too: [ 1, 2, 3 ]
}]
};
const y = {
foo: { baz: 4 },
quux: 5,
array: [{
does: 'work',
too: [ 4, 5, 6 ]
}, {
really: 'yes'
}]
};
const output = merge(x, y);
// Result: {
// foo: { bar: 3, baz: 4 },
// array: [
// { does: 'work', too: [ 1, 2, 3 ] },
// { does: 'work', too: [ 4, 5, 6 ] },
// { really: 'yes' }
// ],
// quux: 5
// }Merge two objects deeply, returning a new merged object with elements from both inputs.
function deepmerge<T>(x: Partial<T>, y: Partial<T>, options?: Options): T;
function deepmerge<T1, T2>(x: Partial<T1>, y: Partial<T2>, options?: Options): T1 & T2;Parameters:
x - Target object to merge intoy - Source object to merge fromoptions - Optional configuration objectReturns: New merged object combining properties from both inputs
Usage Example:
const target = { name: 'John', details: { age: 30 } };
const source = { details: { city: 'NYC' }, active: true };
const result = merge(target, source);
// Result: { name: 'John', details: { age: 30, city: 'NYC' }, active: true }Merge any number of objects into a single result object.
export function all(objects: object[], options?: Options): object;
export function all<T>(objects: Partial<T>[], options?: Options): T;Parameters:
objects - Array of objects to merge (must be an array)options - Optional configuration objectReturns: Single merged object containing all properties
Throws: Error if first argument is not an array
Usage Example:
const foobar = { foo: { bar: 3 } };
const foobaz = { foo: { baz: 4 } };
const bar = { bar: 'yay!' };
const result = merge.all([foobar, foobaz, bar]);
// Result: { foo: { bar: 3, baz: 4 }, bar: 'yay!' }Configure merge behavior through the options parameter.
interface Options {
arrayMerge?: (target: any[], source: any[], options?: ArrayMergeOptions) => any[];
clone?: boolean;
customMerge?: (key: string, options?: Options) => ((x: any, y: any) => any) | undefined;
isMergeableObject?: (value: object) => boolean;
}
interface ArrayMergeOptions {
isMergeableObject(value: object): boolean;
cloneUnlessOtherwiseSpecified(value: object, options?: Options): object;
}By default, arrays are merged by concatenation. Customize this behavior with the arrayMerge option.
Overwrite Arrays Example:
const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray;
const result = merge(
[1, 2, 3],
[3, 2, 1],
{ arrayMerge: overwriteMerge }
);
// Result: [3, 2, 1]Combine Arrays Example:
const combineMerge = (target, source, options) => {
const destination = target.slice();
source.forEach((item, index) => {
if (typeof destination[index] === 'undefined') {
destination[index] = options.cloneUnlessOtherwiseSpecified(item, options);
} else if (options.isMergeableObject(item)) {
destination[index] = merge(target[index], item, options);
} else if (target.indexOf(item) === -1) {
destination.push(item);
}
});
return destination;
};
const result = merge(
[{ a: true }],
[{ b: true }, 'ah yup'],
{ arrayMerge: combineMerge }
);
// Result: [{ a: true, b: true }, 'ah yup']Control which objects are considered mergeable with the isMergeableObject option.
Usage Example:
const { isPlainObject } = require('is-plain-object');
function SuperSpecial() {
this.special = 'oh yeah man totally';
}
const target = { someProperty: { cool: 'oh for sure' } };
const source = { someProperty: new SuperSpecial() };
// Default behavior - merges properties
const defaultOutput = merge(target, source);
// defaultOutput.someProperty instanceof SuperSpecial === false
// Custom behavior - preserves special objects
const customOutput = merge(target, source, {
isMergeableObject: isPlainObject
});
// customOutput.someProperty instanceof SuperSpecial === trueCustomize merge behavior for specific properties using the customMerge option.
Usage Example:
const alex = {
name: { first: 'Alex', last: 'Alexson' },
pets: ['Cat', 'Parrot']
};
const tony = {
name: { first: 'Tony', last: 'Tonison' },
pets: ['Dog']
};
const mergeNames = (nameA, nameB) => `${nameA.first} and ${nameB.first}`;
const options = {
customMerge: (key) => {
if (key === 'name') {
return mergeNames;
}
// Return undefined to use default merge behavior
}
};
const result = merge(alex, tony, options);
// Result: {
// name: 'Alex and Tony',
// pets: ['Cat', 'Parrot', 'Dog']
// }The clone option controls whether child objects are cloned (default: true).
Usage Example:
const target = { nested: { value: 1 } };
const source = { nested: { value: 2 } };
// With cloning (default)
const cloned = merge(target, source);
cloned.nested !== target.nested; // true
// Without cloning (deprecated)
const notCloned = merge(target, source, { clone: false });deepmerge creates new objects and does not modify the original inputs.
const original = { a: 1 };
const addition = { b: 2 };
const result = merge(original, addition);
// original is unchanged
console.log(original); // { a: 1 }
console.log(result); // { a: 1, b: 2 }deepmerge includes protection against prototype poisoning attacks by checking property safety.
When merging values of different types, the source value takes precedence:
const result = merge({ key: [1, 2] }, { key: 'string' });
// Result: { key: 'string' }Enumerable symbol properties are included in the merge process alongside regular string keys.