Back to blog
Guides8 min read

How to Merge JSON Objects: Shallow vs Deep Merge

Merge JSON objects correctly: shallow vs deep merge, how nested keys and arrays are combined, conflict resolution, doing it in JavaScript and Python, and tools that merge JSON without losing data.

By Saifur Rahman Shochib

Merging JSON sounds trivial until nested objects and arrays get involved, and a careless merge silently discards data. Combining a base config with an override, stitching two API responses together, or layering defaults all depend on knowing the difference between a shallow and a deep merge. This guide explains both, how conflicts and arrays are handled, and how to merge JSON without losing anything.

Shallow versus deep merge

A shallow merge combines only the top-level keys: when both objects have a key, the second object's value wins and entirely replaces the first — even if that value is a nested object. A deep merge recurses into nested objects, combining them key by key at every level rather than overwriting whole branches. The difference is enormous: a shallow merge of two config objects can wipe out an entire nested section that you meant to extend.

What happens to nested objects

Consider a base with {"db": {"host": "localhost", "port": 5432}} and an override with {"db": {"port": 5433}}. A shallow merge replaces the whole db object, losing host. A deep merge keeps host and updates only port, giving the result you almost always want for configuration. This is why config systems use deep merge: overrides should patch, not replace.

Shallow merge replaces nested objects; deep merge combines themjavascript
const base     = { db: { host: "localhost", port: 5432 } };
const override = { db: { port: 5433 } };

// Shallow ( { ...base, ...override } ) — host is LOST:
// → { db: { port: 5433 } }

// Deep merge — host is kept:
// → { db: { host: "localhost", port: 5433 } }

How arrays are handled

Arrays are the ambiguous case with no single right answer. A merge can replace the array wholesale, concatenate both arrays, or merge elements by index or by a key. Most deep-merge implementations replace arrays by default, which surprises people who expected concatenation. Decide explicitly how your merge should treat arrays, because the wrong choice quietly drops or duplicates list items.

Conflict resolution

When the same key holds different scalar values, the merge needs a rule. The common default is last-wins: the later object overrides the earlier one, which is exactly what you want when layering an override on top of a base. Some merges let you reverse precedence or supply a custom resolver. Know which object takes priority before you merge, especially when combining more than two sources.

Merging in code

In JavaScript, the spread operator {...a, ...b} and Object.assign both do a shallow merge — convenient but dangerous for nested data, since they replace whole sub-objects. Deep merge requires a recursive function or a library helper. In Python, dict.update and the union operator are shallow too, so nested merges need a recursive routine. Always confirm whether your tool is shallow before trusting it with nested config.

Merging JSON safely

For one-off merges, a JSON Merge tool combines objects in your browser and lets you see the result before you use it, which avoids the silent data loss of a shallow merge. When you need to express the difference between two documents as a set of changes rather than a merged whole, a JSON Patch generator produces an operation list, and a compare tool shows exactly what differs first.

Frequently asked questions

What is the difference between a shallow and deep merge?

A shallow merge combines only top-level keys and replaces whole nested values when keys collide. A deep merge recurses into nested objects and combines them key by key at every level. Use deep merge for config so overrides patch rather than replace nested sections.

Does the JavaScript spread operator deep merge?

No. Both the spread operator ({...a, ...b}) and Object.assign perform a shallow merge — a colliding key's nested object is replaced entirely, not merged. For nested data you need a recursive deep-merge function or a library helper.

How are arrays handled when merging JSON?

It depends on the implementation. Arrays may be replaced wholesale, concatenated, or merged by index or key. Most deep-merge tools replace arrays by default, so decide explicitly how you want arrays handled to avoid dropping or duplicating items.

Which value wins when merging JSON objects?

By the common last-wins rule, the later object overrides the earlier one for conflicting keys — ideal for layering an override on a base. Some merge tools let you reverse precedence or provide a custom resolver.

How do I merge two JSON files without losing data?

Use a deep merge so nested objects are combined rather than replaced, and decide how arrays should be handled. A JSON merge tool lets you preview the combined result, avoiding the silent data loss that a shallow merge can cause.

Related tools

Try these tools

Keep reading

Related guides