deep-extend
Recursive deep-merge and deep-clone utility for JavaScript objects, arrays, dates, regexps, and buffers.
Repository Health
Technical Analysis
deep-extend is a lightweight, dependency-free JavaScript utility that recursively merges the properties of one or more source objects into a target object, similar in spirit to jQuery.extend or Lodash’s merge but scoped to a single focused function. It walks nested objects and arrays, copying properties layer by layer rather than overwriting whole subtrees, so deeply nested configuration objects merge cleanly instead of clobbering each other.
Beyond plain objects, it special-cases Buffer, Date, and RegExp instances so they are cloned correctly instead of being merged as if they were plain objects, and it clones arrays element-by-element, recursing into nested objects, rather than merging them by index. Passing an empty object as the first argument turns the same function into a deep-clone utility, a pattern documented directly in the README. Its single-purpose design and long-standing presence in the npm ecosystem (published since 2011) have made it a common transitive dependency in build tools and config-merging code across the Node ecosystem.
What You Get
- Recursive merge of nested plain objects across any number of source arguments
- Correct cloning of Date, RegExp, and Buffer instances instead of naive property copying
- Array cloning that recurses into nested objects rather than merging by index
- A dual-purpose API — pass an empty object as the target to use it as a deep-clone function
Common Use Cases
- Merging default configuration objects with user-supplied overrides in CLI tools and build systems
- Deep-cloning nested state objects without mutating the original
- Combining partial API response fragments into one accumulated object
- Layering environment-specific config files (base, dev, prod) into a single resolved config
Under The Hood
Architecture
deep-extend ships as a single-file module (lib/deep-extend.js), with index.js acting as a thin re-export shim. There is no layering or dependency injection — it’s a flat, single-function utility built around one recursive deepExtend closure that dispatches to small helper functions (isSpecificValue, cloneSpecificValue, deepCloneArray, safeGetProperty) for cloning special values and arrays. Behavior is determined entirely by the runtime types of the arguments passed in, with no exposed configuration. Because every code path routes through the same recursive dispatch chain of typeof/instanceof checks, that chain is the one place where added complexity would have to live if the library ever grew.
Tech Stack
The module is plain CommonJS JavaScript with no build step or transpilation, targeting Node >=4.0.0 per its engines field. Its only devDependencies are mocha 5.2.0 and should 13.2.1 for testing; there is no bundler, TypeScript, or linter configuration. Tests run via ./node_modules/.bin/mocha, and CI is configured through a .travis.yml file for Travis CI. Publishing is simple: only index.js and lib/ are whitelisted in package.json’s files field.
Code Quality
A single spec file (test/index.spec.js) using mocha and should covers the documented edge cases — nested object merging, arrays, Date, RegExp, and Buffer handling. Error handling is minimal and intentional: invalid input returns false rather than throwing, favoring a quiet fallback over a typed error. There are no shipped type definitions and no linter or formatter configuration, though naming is terse and consistent across the small set of helper functions.
What Makes It Unique
Recursive deep-merging is a well-trodden pattern shared by jQuery.extend, Lodash’s merge, and many similar utilities, so deep-extend doesn’t introduce a novel algorithm. It does encode a specific, deliberate set of edge-case decisions that not every merge implementation makes: type-aware cloning for Buffer, Date, and RegExp instead of generic property copying, explicit __proto__ key filtering to guard against prototype pollution, and reusing one function for both merging and cloning depending on what’s passed as the target.
Used by 2 apps in this directory
Novu
Developer Tools
Open-source communication infrastructure that connects your products and AI agents to every channel your users live on — Inbox, Email, SMS, Push, Chat, and more.
swagger-ui
Developer Tools
Transform OpenAPI specifications into interactive, browser-based API documentation that developers and consumers can explore and test live.