---
title: "deepMerge"
description: "Recursively merge multiple objects into a new one, with configurable array strategies, null handling, and custom per-key mergers."
canonical_url: "https://core.mhaibaraai.cn/en/docs/helpers/object/deep-merge"
---
# deepMerge

> Recursively merge multiple objects into a new one, with configurable array strategies, null handling, and custom per-key mergers.

## Usage

The `deepMerge` function recursively merges multiple source objects into a new object without modifying any input.

Later sources take priority. Properties that are plain objects on both sides are merged recursively instead of overwritten. Symbol keys are supported and prototype pollution is prevented.

```ts
import { deepMerge } from '@movk/core'

const defaults = { theme: 'light', pagination: { page: 1, size: 10 } }
const userConfig = { pagination: { size: 20 }, debug: true }

const result = deepMerge([defaults, userConfig])
// => { theme: 'light', pagination: { page: 1, size: 20 }, debug: true }
```

### Array merge strategy

```ts
// concat (default): concatenate arrays
deepMerge([{ tags: ['a'] }, { tags: ['b'] }])
// => { tags: ['a', 'b'] }

// replace: replace entirely
deepMerge([{ tags: ['a'] }, { tags: ['b'] }], { arrayStrategy: 'replace' })
// => { tags: ['b'] }

// unique: concatenate and deduplicate
deepMerge([{ tags: ['a', 'b'] }, { tags: ['b', 'c'] }], { arrayStrategy: 'unique' })
// => { tags: ['a', 'b', 'c'] }
```

### null/undefined handling

```ts
// skip (default): ignore null/undefined from source
deepMerge([{ a: 1 }, { a: null }])
// => { a: 1 }

// override: allow null/undefined to overwrite
deepMerge([{ a: 1 }, { a: null }], { nullHandling: 'override' })
// => { a: null }
```

### Custom merger

```ts
// add numbers instead of overwriting
const result = deepMerge(
  [{ count: 10 }, { count: 5 }],
  {
    customMerger: (key, targetVal, sourceVal) => {
      if (typeof targetVal === 'number' && typeof sourceVal === 'number')
        return targetVal + sourceVal
      return undefined // fall through to default logic
    },
  },
)
// => { count: 15 }
```

## createDeepMerge

Use `createDeepMerge` to create a merge function with pre-bound options, avoiding the need to pass options on every call.

```ts
import { createDeepMerge } from '@movk/core'

const mergeReplace = createDeepMerge({ arrayStrategy: 'replace' })

mergeReplace([{ tags: ['a'] }, { tags: ['b'] }])
// => { tags: ['b'] }
```

## API

### `deepMerge<T>(sources, options?)`

Recursively deep-merges multiple objects.

### Parameters

**sources** (`T[]`) *required*: Array of source objects to merge. Later objects take priority.

**options** (`DeepMergeOptions`): Options to control merge behavior.

### Returns

**returns** (`T`): A new merged object; no input is modified.

### DeepMergeOptions

**arrayStrategy** (`'concat' | 'replace' | 'unique'`): Array merge strategy. Defaults to 'concat'.

**nullHandling** (`'skip' | 'override'`): How to handle null/undefined from source. Defaults to 'skip'.

**customMerger** (`CustomMerger`): Custom merge function. Return undefined to fall through to default logic.

### `createDeepMerge(options)`

Creates a `deepMerge` function with pre-bound options.

### Parameters

**options** (`DeepMergeOptions`) *required*: Options to control merge behavior.

### Returns

**returns** (`<T>(sources: T[]) => T`): A pre-configured deepMerge function.

## Changelog

See commit history for [src/helpers/object/deepMerge.ts](https://github.com/mhaibaraai/movk-core/commits/main/src/helpers/object/deepMerge.ts).

---

- [GitHub](https://github.com/mhaibaraai/movk-core/blob/main/src/helpers/object/deepMerge.ts)


## Sitemap

See the full [sitemap](https://core.mhaibaraai.cn/sitemap.md) for all pages.
