or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-deepmerge

A library for deep (recursive) merging of Javascript objects

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/deepmerge@4.3.x

To install, run

npx @tessl/cli install tessl/npm-deepmerge@4.3.0

index.mddocs/

deepmerge

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.

Package Information

  • Package Name: deepmerge
  • Package Type: npm
  • Language: JavaScript (with TypeScript definitions)
  • Installation: npm install deepmerge
  • Main Entry: dist/cjs.js (CommonJS)
  • Browser Usage: Available as UMD from unpkg.com

Core Imports

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>

Basic Usage

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
// }

Capabilities

Deep Object Merging

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 into
  • y - Source object to merge from
  • options - Optional configuration object

Returns: 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 }

Multiple Object Merging

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 object

Returns: 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!' }

Configuration Options

Merge Options

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;
}

Array Merge Customization

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']

Object Mergeability Control

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 === true

Property-Specific Merging

Customize 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']
// }

Clone Control

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 });

Important Behaviors

Immutability

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 }

Prototype Pollution Protection

deepmerge includes protection against prototype poisoning attacks by checking property safety.

Type Precedence

When merging values of different types, the source value takes precedence:

const result = merge({ key: [1, 2] }, { key: 'string' });
// Result: { key: 'string' }

Symbol Property Support

Enumerable symbol properties are included in the merge process alongside regular string keys.