The Lodash method _.merge exported as a module for deep recursive merging of object properties.
npx @tessl/cli install tessl/npm-lodash--merge@4.6.0Lodash Merge provides deep recursive merging of object properties. This standalone Node.js module exports the Lodash _.merge method as a single function, enabling sophisticated object composition with predictable deep-merge semantics.
npm install lodash.mergeconst merge = require('lodash.merge');For ES6 modules (with transpilation):
import merge from 'lodash.merge';const merge = require('lodash.merge');
// Basic object merging
const object = {
'a': [{ 'b': 2 }, { 'd': 4 }]
};
const other = {
'a': [{ 'c': 3 }, { 'e': 5 }]
};
merge(object, other);
// => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
// Multiple sources
const defaults = { 'theme': 'light', 'timeout': 5000 };
const userConfig = { 'theme': 'dark' };
const envConfig = { 'debug': true };
const config = merge({}, defaults, userConfig, envConfig);
// => { 'theme': 'dark', 'timeout': 5000, 'debug': true }Recursively merges own and inherited enumerable string keyed properties of source objects into the destination object. Array and plain object properties are merged recursively, while other objects and value types are overridden by assignment.
/**
* Recursively merges own and inherited enumerable string keyed properties
* of source objects into the destination object. Source properties that resolve
* to `undefined` are skipped if a destination value exists. Array and plain
* object properties are merged recursively. Other objects and value types are
* overridden by assignment. Source objects are applied from left to right.
* Subsequent sources overwrite property assignments of previous sources.
*
* **Note:** This method mutates `object`.
*
* @param {Object} object The destination object.
* @param {...Object} [sources] The source objects.
* @returns {Object} Returns `object`.
*/
function merge(object, ...sources);Parameters:
object (Object): The destination object (required, will be mutated)...sources (Object[]): The source objects to merge from (optional, variadic)Returns:
Object: Returns the mutated destination objectKey Behaviors:
object parameter is directly modifiedundefined are skipped if destination value existsUsage Examples:
const merge = require('lodash.merge');
// Nested object merging
const object = {
user: {
name: 'John',
preferences: {
theme: 'light',
notifications: { email: true }
}
}
};
const updates = {
user: {
age: 30,
preferences: {
theme: 'dark',
notifications: { push: true }
}
}
};
merge(object, updates);
// Result: {
// user: {
// name: 'John',
// age: 30,
// preferences: {
// theme: 'dark',
// notifications: { email: true, push: true }
// }
// }
// }
// Array merging behavior
const arrayMerge = {
items: [
{ id: 1, name: 'first' },
{ id: 2, name: 'second' }
]
};
const arrayUpdate = {
items: [
{ id: 1, description: 'updated first' },
{ id: 2, active: true }
]
};
merge(arrayMerge, arrayUpdate);
// Result: {
// items: [
// { id: 1, name: 'first', description: 'updated first' },
// { id: 2, name: 'second', active: true }
// ]
// }
// Multiple source merging
const base = { a: 1, b: { x: 1 } };
const source1 = { b: { y: 2 }, c: 3 };
const source2 = { b: { z: 3 }, d: 4 };
merge(base, source1, source2);
// Result: { a: 1, b: { x: 1, y: 2, z: 3 }, c: 3, d: 4 }
// Configuration merging pattern
const defaultConfig = {
server: {
port: 3000,
host: 'localhost',
ssl: {
enabled: false,
cert: '',
key: ''
}
},
database: {
host: 'localhost',
port: 5432,
pool: { min: 2, max: 10 }
}
};
const envConfig = {
server: {
port: process.env.PORT || 8080,
ssl: {
enabled: true,
cert: '/path/to/cert.pem'
}
}
};
const userConfig = {
database: {
host: 'prod-db.example.com',
pool: { max: 20 }
}
};
const finalConfig = merge({}, defaultConfig, envConfig, userConfig);
// Deep merges all configurations with user config taking final precedenceUnlike Object.assign() which performs shallow copying, merge() handles nested structures:
const merge = require('lodash.merge');
const target = {
settings: {
theme: 'light',
features: { search: true }
}
};
const source = {
settings: {
language: 'en',
features: { notifications: true }
}
};
// With Object.assign (shallow)
const assigned = Object.assign({}, target, source);
// Result: { settings: { language: 'en', features: { notifications: true } } }
// Notice: theme and search are lost!
// With merge (deep)
const merged = merge({}, target, source);
// Result: {
// settings: {
// theme: 'light',
// language: 'en',
// features: { search: true, notifications: true }
// }
// }The merge function gracefully handles various edge cases:
constructor and __proto__ properties are safely handledconst merge = require('lodash.merge');
// Safe handling of edge cases
const result = merge(
{ a: 1 },
null, // ignored
undefined, // ignored
{ b: 2 }, // merged
{ a: 'override' } // overrides a: 1
);
// Result: { a: 'override', b: 2 }const merge = require('lodash.merge');
// Hierarchical configuration merging
const defaultConfig = require('./config/default.json');
const environmentConfig = require(`./config/${NODE_ENV}.json`);
const userConfig = process.env.USER_CONFIG ? JSON.parse(process.env.USER_CONFIG) : {};
const config = merge({}, defaultConfig, environmentConfig, userConfig);const merge = require('lodash.merge');
function updateState(currentState, updates) {
return merge({}, currentState, updates);
}
// Preserves nested state while applying selective updates
const newState = updateState(
{ user: { profile: { name: 'John' }, settings: { theme: 'light' } } },
{ user: { settings: { notifications: true } } }
);const merge = require('lodash.merge');
async function fetchUserWithPreferences(userId) {
const [user, preferences, settings] = await Promise.all([
fetchUser(userId),
fetchUserPreferences(userId),
fetchUserSettings(userId)
]);
return merge({}, user, { preferences }, { settings });
}