Extend Shallow
extend-shallow is a minimalist JavaScript utility designed to merge the enumerable properties of one or more source objects into a target object. It performs a *shallow* merge, meaning only top-level properties are copied; nested objects or arrays are copied by reference rather than being cloned. The current stable version is 3.0.2, last published in 2017, indicating a mature and stable, but not actively feature-developed, codebase. It primarily targets Node.js environments from version 0.10.0 upwards, supporting CommonJS module syntax. While modern JavaScript environments widely support `Object.assign()` for similar functionality, extend-shallow serves as a lightweight alternative, particularly useful in legacy environments or when a direct, unopinionated shallow merge is explicitly required without the overhead of polyfills or broader compatibility layers. Its key differentiator lies in its focused, single-purpose design, making it a very small footprint utility.
Common errors
-
TypeError: extend_shallow_1.extend is not a function
cause This error typically occurs when using TypeScript or ESM and attempting a named import (e.g., `import { extend } from 'extend-shallow';`) from a CommonJS module that only provides a default export.fixUse a default import for ESM (`import extend from 'extend-shallow';`) or the CommonJS `require` syntax (`const extend = require('extend-shallow');`). -
TypeError: Cannot set property 'someProp' of undefined (or null)
cause The first argument to `extend-shallow` (the target object) must be a non-null, non-undefined object. If `null`, `undefined`, or a primitive value is passed as the target, attempts to assign properties will fail.fixEnsure the first argument passed to `extend` is always an object, typically an empty object literal `{}` if you intend to create a new object or an existing object you wish to mutate.
Warnings
- gotcha extend-shallow performs a shallow merge. This means that only top-level properties are copied by value. Nested objects or arrays within source objects are copied by reference to the target object. Modifying a nested property in the target object will therefore affect the original source object if they share the same reference.
- gotcha This package is a CommonJS module and does not natively support ES Modules (ESM) named imports. Attempting `import { extend } from 'extend-shallow'` will result in a runtime error or unexpected `undefined` value.
- gotcha While still functional and stable, extend-shallow is largely superseded by the native JavaScript method `Object.assign()`. `Object.assign()` provides similar shallow merging capabilities and is widely supported in modern JavaScript environments (ES6+).
Install
-
npm install extend-shallow -
yarn add extend-shallow -
pnpm add extend-shallow
Imports
- extend
import { extend } from 'extend-shallow';const extend = require('extend-shallow'); - extend (ESM)
import * as extend from 'extend-shallow';
import extend from 'extend-shallow';
Quickstart
const extend = require('extend-shallow');
// Basic shallow extension
const targetObj = { a: 1, b: { c: 2 } };
const sourceObj1 = { b: { d: 3 }, e: 4 };
const sourceObj2 = { f: 5 };
const result = extend(targetObj, sourceObj1, sourceObj2);
console.log('Extended object:', result);
// Expected output: { a: 1, b: { d: 3 }, e: 4, f: 5 }
// Note: b from sourceObj1 overwrites b from targetObj. Nested {d:3} is copied by reference.
// Shallow clone by extending into an empty object
const original = { x: 10, y: { z: 20 } };
const clone = extend({}, original);
console.log('Shallow clone:', clone);
console.log('Is original.y === clone.y?', original.y === clone.y); // true, because it's a shallow copy
// Demonstrating the shallow copy behavior
clone.y.z = 99;
console.log('Original after modifying clone.y:', original);
// Expected: Original will also show { x: 10, y: { z: 99 } } because y is a shared reference.