npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@komed3/deepmerge

v1.0.0

Published

Fast and efficient deep object merging and manipulation library

Readme

@komed3/deepmerge

A fast and efficient deep object merging and manipulation library for Node.js and the browser, optimized for performance and flexibility.

deepmerge provides a high-performance Merger with a non-recursive stack-based implementation and a versatile Accessor for safe, deep object manipulation using dot and bracket notation. It includes a built-in path compiler with caching to ensure maximum efficiency during repeated operations.

Installation

Install via npm:

npm install @komed3/deepmerge

Import Methods

deepmerge supports multiple module formats for seamless integration across different environments.

ESM (ECMAScript Modules)

For modern projects using import:

import { factory, Merger, Accessor } from '@komed3/deepmerge';

CommonJS

For Node.js projects using require:

const { factory, Merger, Accessor } = require( '@komed3/deepmerge' );

UMD (Browser)

Include the script in your HTML:

<script src="node_modules/@komed3/deepmerge/dist/index.umd.min.js"></script>
<script>
    const { factory } = deepmerge;
</script>

Quick Usage

The easiest way to get started is using the factory() function to create a new instance with a shared configuration.

import { factory } from '@komed3/deepmerge';

// initialize with default options
const qm = factory();

const target = { user: { name: 'Max' } };
const source = { user: { role: 'admin' }, tags: [ 'lead' ] };

// deep merge objects
qm.merger.merge( target, source );
console.log( target ); // { user: { name: 'Max', role: 'admin' }, tags: [ 'lead' ] }

// safe property access using dot/bracket notation
const name = qm.accessor.get( target, 'user.name' ); // 'Max'
qm.accessor.set( target, 'user.id', 123 );
qm.accessor.update( target, 'tags[0]', v => v.toUpperCase() );

console.log( target.user.id ); // 123
console.log( target.tags ); // [ 'LEAD' ]

Instead of using the factory function, you can also create instances of Merger, Accessor, and Path directly:

import { Merger, Accessor, Path } from '@komed3/deepmerge';

const merger = new Merger( { ... } );
const accessor = new Accessor( { ... } );
const path = new Path( { ... } );

API Reference

factory( options? )

Creates an object containing pre-configured instances of Merger, Accessor, and Path.

const { merger, accessor, path } = factory( { deep: true, protect: false } );

Merger

  • merge< T >( target: T, ...sources: any[] ) : T
    Performs a deep merge of all source objects into the target.
  • mergeAt< T >( target: T, path: PathLike, ...sources: any[] ) : T
    Merges sources into the target at a specific nested path.

Accessor

  • get< O, V >( obj: O, path: PathLike ) : V | undefined
    Retrieves a value at the given path.
  • set< O, V >( obj: O, path: PathLike, value: V ) : void
    Sets a value at the path, creating missing structures if needed.
  • has< O >( obj: O, path: PathLike ) : boolean
    Checks if a nested property exists.
  • delete< O >( obj: O, path: PathLike ) : void
    Removes a property or array index at the path.
  • update< O >( obj: O, path: PathLike, fn: ( v: any ) => any ) : void
    Transforms a value at the path using a function.

Path

  • compile( path: string ) : CompiledPath
    Parses a path string into tokens and caches the result.
  • normalize( path: PathLike ) : CompiledPath
    Ensures a path is in its compiled format.

Options

MergeOptions

  • deep (boolean, default: true)
    Whether to perform deep merging of nested objects.
  • protect (boolean, default: false)
    If true, existing properties in the target are not overwritten.
  • mergeUndefined (boolean, default: false)
    Whether to allow undefined values from sources to overwrite target values.
  • strict (boolean, default: false)
    If true, new objects/arrays will not be created when paths are missing.
  • createObject (function, default: () => Object.create( null ))
    A factory function for creating new objects when missing structures are encountered during a deep merge.
  • arrayMode ('replace' | 'keep' | 'concat' | 'unique' | function, default: 'replace')
    Strategy for merging arrays or a custom merge function ( target: any[], source: any[] ) => any[].
  • valueFn (function)
    A custom function to handle specific value merging logic: ( key, targetVal, sourceVal ) => any.
  • pathOptions (PathOptions)
    Configuration for the internal path compiler.

PathOptions

  • cache (boolean, default: true)
    Enable or disable caching of compiled path strings.
  • maxCacheSize (number, default: 1000)
    The maximum number of paths to keep in the cache.

Customization

Custom Object Creation

Use createObject to control how new objects are instantiated, for example to use plain objects instead of null-prototype objects:

const qm = factory( {
  createObject: () => ( {} )
} );

Custom Array Merging

Pass a function to arrayMode to implement your own logic, such as merging by a specific property:

const qm = factory( {
  arrayMode: ( target, source ) => {
    // custom merge logic
    return [ ...target, ...source ].filter( v => v.active );
  }
} );

Custom Value Merging

Use valueFn to define custom logic for merging individual values:

const qm = factory( {
  valueFn: ( key, targetVal, sourceVal ) => {
    if ( key === 'count' ) {
      return targetVal + sourceVal;
    }
    return sourceVal;
  }
} );

Array Modes

Control how arrays are handled during a merge using the built-in ArrayMode enums:

  • Replace: Overwrites the target array with the source array (default).
  • Keep: Retains the target array and ignores the source.
  • Concat: Appends source elements to the target array.
  • Unique: Combines both arrays and removes duplicates.
import { factory, ArrayMode } from '@komed3/deepmerge';

const qm = factory( { arrayMode: ArrayMode.Unique } );
const target = { ids: [ 1, 2 ] };
qm.merger.merge( target, { ids: [ 2, 3 ] } );

console.log( target.ids ); // [ 1, 2, 3 ]

Copyright (c) 2026 Paul Köhler (komed3). All rights reserved.
Released under the MIT license. See LICENSE file in the project root for details.