Skip to content
ZeroServer.tools

JSON Merge

Deep-merge or shallow-merge two JSON documents. Choose whether arrays are replaced, concatenated or merged by index; every key and number is kept as written.

Merge
Arrays

About JSON Merge

A deep merge combines two JSON documents all the way down: where both hold an object at the same key, the two objects are merged too, and JSON 2's value wins any other conflict. A shallow merge combines only the top level, so JSON 2's value replaces JSON 1's outright, as { ...a, ...b } and Object.assign({}, a, b) do in JavaScript. Arrays have no single rule, so the Arrays option chooses: JSON 2's array replaces JSON 1's, as in a JSON Merge Patch (RFC 7396); the two are concatenated; or they are merged by index, as lodash's merge does. JSON 1's keys keep their order, and the keys only JSON 2 has follow. Any key is read as a key, __proto__ and constructor included, and each number keeps its digits, so a 20-digit ID is not rounded and 59.90 stays 59.90. Notes under the result say where JSON 2 replaced an object or an array with a value of another type, and what a shallow merge dropped.

Built and maintained by Meet Shah · Last updated

What this tool is used for

  • Layering an environment override file on top of a base configuration to see the effective result.
  • Combining a default settings object with a user's saved preferences, then swapping the two to check which order your code needs.
  • Building a single fixture from two partial API responses.
  • Checking how your library merges, deep or shallow, and whether it replaces arrays, concatenates them or merges them by index.
  • Producing a merged payload to send in one request instead of two.

Frequently Asked Questions

What is the difference between a shallow and a deep merge?
A shallow merge replaces whole top-level values, so a nested object in JSON 2 overwrites JSON 1's entirely, as { ...a, ...b } does. A deep merge recurses and combines nested objects key by key. Most surprises come from expecting deep and getting shallow, so a shallow merge here notes what it dropped.
How are arrays handled?
There is no single rule, so the Arrays option chooses. Replace takes JSON 2's array, as Object.assign, spread and a JSON Merge Patch (RFC 7396) do. Concatenate puts JSON 2's items after JSON 1's. Merge by index merges the items at each position, as lodash's merge does, so [1, 2] and [3] give [3, 2].
How do I delete a key when merging?
A merge cannot: a null in JSON 2 sets the value to null, as Object.assign and lodash's merge do. In a JSON Merge Patch (RFC 7396) null means remove instead, which is also why a merge patch cannot set a value to null. To remove keys, write the change as a merge patch and apply it with the JSON Merge Patch tool.
What is the difference from JSON Patch?
A JSON Merge Patch (RFC 7396) looks like the document and is applied much like a deep merge, except that null removes a key and an array is replaced whole. JSON Patch (RFC 6902) is an explicit list of add, remove, replace, move, copy and test operations: more verbose, but it can set a null and change one array element.
Which input wins on a conflict?
JSON 2, the later one, by the same rule as Object.assign and spread. Order therefore matters, and merging defaults over user settings rather than under them is a frequent bug. The Swap button exchanges the two documents, so the other order is one click away.
What happens when the two sides have different types for a key?
JSON 2's value replaces JSON 1's outright: an object is not merged into a string. This is where silent data loss hides, since the result is valid JSON, so a note names each place where an object or an array in JSON 1 was replaced by a value of another type.
Is a deep merge associative?
Almost. Merging (A with B) with C matches merging A with (B with C), unless a place holds an object in A and C, or an array in both, and another type in B. With A {"k": {"x": 1}}, B {"k": 5} and C {"k": {"y": 2}}, the first order gives {"k": {"y": 2}} and the second {"k": {"x": 1, "y": 2}}.
Are numbers and keys kept exactly?
Yes. A merge through JSON.parse and JSON.stringify rounds 12345678901234567890 to 12345678901234567000, writes 59.90 as 59.9, and moves a key such as "10" to the front. Here each number is written as it was, JSON 1's keys keep their order with JSON 2's new keys after them, and __proto__ is an ordinary key.

Common errors and gotchas

  • Assuming every merge treats arrays alike. Object.assign and a JSON Merge Patch replace an array whole, while lodash's merge merges it by index, so there [1, 2] and [3] give [3, 2].
  • Choosing a shallow merge and losing every nested key that JSON 2 did not mention.
  • Assuming null in JSON 2 removes a key. A merge sets the value to null; only a JSON Merge Patch reads null as remove.
  • Diffing the merged file against one written by another tool, and reading a change of key order as a change of data. JSON parsers ignore key order.
  • Merging through JSON.parse and JSON.stringify and trusting the numbers: a 20-digit ID is rounded, 59.90 becomes 59.9, and 1e400 becomes null.

Related Formatters & Validators tools

Private & free — this tool runs entirely in your browser.

IndieKit — Ship your Next.js startup in days.affiliate