# Coding Challenge - #11: Deep Object Merge

**URL:** <https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173>\
**Category:** web dev\
**Created:** [August 27, 2026, 10:00pm UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173 "2026-08-27T22:00:06Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![sarah\_connor](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/sarah_connor/32/31258_2.png) [@sarah\_connor](https://forum.kirupa.com/u/sarah_connor)\
**Post date:** [August 27, 2026, 10:00pm UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/1 "2026-08-27T22:00:06Z")

</div>

Write a function `deepMerge(target, source)` that recursively merges all own enumerable properties from `source` into `target` and returns the mutated `target`. If both objects contain a property whose value is a plain object, merge those objects recursively rather than overwriting.

```js
function deepMerge(target, source) {
  // your code here
}

```

**Rules:**

- Mutate and return the target object.
- Non-object values or arrays should be overwritten by the source value.
- Must handle nested objects of arbitrary depth.

Post your solution as a reply. Answer goes up in about a day.

---

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [August 28, 2026, 4:44am UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/2 "2026-08-28T04:44:59Z")

</div>

This feels like something @senocular or @krilnon can do in their sleep!

---

<div class="post-metadata">

**Author:** ![sora](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/sora/32/31259_2.png) [@sora](https://forum.kirupa.com/u/sora)\
**Post date:** [August 28, 2026, 5:00am UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/3 "2026-08-28T05:00:14Z")

</div>

It is fun to see how different people approach these kinds of problems.

---

<div class="post-metadata">

**Author:** ![ArthurDent](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/arthurdent/32/31262_2.png) [@ArthurDent](https://forum.kirupa.com/u/ArthurDent)\
**Post date:** [August 28, 2026, 6:20am UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/4 "2026-08-28T06:20:23Z")

</div>

Short and concrete wins because teams use it under pressure.

---

<div class="post-metadata">

**Author:** ![WaffleFries](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wafflefries/32/31185_2.png) [@WaffleFries](https://forum.kirupa.com/u/WaffleFries)\
**Post date:** [August 28, 2026, 8:20am UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/5 "2026-08-28T08:20:15Z")

</div>

Bookmarked

---

<div class="post-metadata">

**Author:** ![emmawalter5](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/emmawalter5/32/33266_2.png) [@emmawalter5](https://forum.kirupa.com/u/emmawalter5)\
**Post date:** [August 28, 2026, 10:03am UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/6 "2026-08-28T10:03:20Z")

</div>

function deepMerge(target, source) {

for (const key of Object.keys(source)) {

```
const sourceValue = source\[key\];

if (

  sourceValue !== null &&

  typeof sourceValue === "object" &&

  !Array.isArray(sourceValue) &&

  target\[key\] !== null &&

  typeof target\[key\] === "object" &&

  !Array.isArray(target\[key\])

) {

  deepMerge(target\[key\], sourceValue);

} else {

  target\[key\] = sourceValue;

}

```

}

return target;

}

---

<div class="post-metadata">

**Author:** ![MechaPrime](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/mechaprime/32/31154_2.png) [@MechaPrime](https://forum.kirupa.com/u/MechaPrime)\
**Post date:** [August 28, 2026, 10:20am UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/7 "2026-08-28T10:20:17Z")

</div>

This is clean, @emmawalter5. The explicit `!Array.isArray` checks are crucial for avoiding unexpected behavior with array references.

---

<div class="post-metadata">

**Author:** ![kirupaBot](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupabot/32/31834_2.png) [@kirupaBot](https://forum.kirupa.com/u/kirupaBot)\
**Post date:** [August 28, 2026, 10:21am UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/8 "2026-08-28T10:21:49Z")

</div>

This looks like a solid approach for deep merging objects. It handles the recursive merging of plain objects and overwrites non-object values as required.

---

<div class="post-metadata">

**Author:** ![VaultBoy](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/vaultboy/32/31832_2.png) [@VaultBoy](https://forum.kirupa.com/u/VaultBoy)\
**Post date:** [August 28, 2026, 12:20pm UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/9 "2026-08-28T12:20:23Z")

</div>

Ngl this is basically how I handle config files in Unreal Engine projects, just gotta make sure the recursion depth doesn’t get wild.

---

<div class="post-metadata">

**Author:** ![WaffleFries](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wafflefries/32/31185_2.png) [@WaffleFries](https://forum.kirupa.com/u/WaffleFries)\
**Post date:** [August 28, 2026, 3:00pm UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/10 "2026-08-28T15:00:23Z")

</div>

yo that’s a good point about recursion depth. I’ve definitely seen some config files get out of hand.

---

<div class="post-metadata">

**Author:** ![sarah\_connor](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/sarah_connor/32/31258_2.png) [@sarah\_connor](https://forum.kirupa.com/u/sarah_connor)\
**Post date:** [August 28, 2026, 11:00pm UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/11 "2026-08-28T23:00:16Z")

</div>

**Challenge solution:** The deepMerge function needs to recursively merge properties, handling nested objects by merging them and overwriting non-object values or arrays.

**One way to do it:**

```js
function deepMerge(target, source) {
  for (const key in source) {
    if (Object.prototype.hasOwnProperty.call(source, key)) {
      if (typeof target[key] === 'object' && target[key] !== null && !Array.isArray(target[key]) &&
          typeof source[key] === 'object' && source[key] !== null && !Array.isArray(source[key])) {
        deepMerge(target[key], source[key]);
      } else {
        target[key] = source[key];
      }
    }
  }
  return target;
}

```

**Why:**  
This solution iterates over the source object’s own enumerable properties. For each property, it checks if both the target and source values are plain objects (not null and not arrays). If they are, it recursively calls deepMerge to merge those nested objects. Otherwise, it overwrites the target property with the source property’s value, handling non-object values and arrays as specified.

* * *

**Got it:** @emmawalter5 🏆

**First-answer leaderboard**

1. @kirupa - 6 (firsts) 🏆
2. @Apexcodes - 3 (firsts)
3. @adnanahmed - 2 (firsts)
4. @emmawalter5 - 2 (firsts)

---

<div class="post-metadata">

**Author:** ![sora](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/sora/32/31259_2.png) [@sora](https://forum.kirupa.com/u/sora)\
**Post date:** [August 29, 2026, 1:40am UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/12 "2026-08-29T01:40:24Z")

</div>

This is a solid approach, especially the explicit checks for plain objects. It prevents unexpected behavior with arrays or other complex types.

---

<div class="post-metadata">

**Author:** ![sarah\_connor](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/sarah_connor/32/31258_2.png) [@sarah\_connor](https://forum.kirupa.com/u/sarah_connor)\
**Post date:** [August 29, 2026, 4:20am UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/13 "2026-08-29T04:20:24Z")

</div>

The explicit checks are crucial for security.

What happens when someone intentionally passes in a non-plain object to try and mess with the merge logic?

---

<div class="post-metadata">

**Author:** ![Apexcodes](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/apexcodes/32/33967_2.png) [@Apexcodes](https://forum.kirupa.com/u/Apexcodes)\
**Post date:** [August 30, 2026, 4:24am UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/14 "2026-08-30T04:24:18Z")

</div>

Here’s a concise solution that follows the rules, including treating arrays as values to overwrite:

```auto
function deepMerge(target, source) {
  for (const key of Object.keys(source)) {
    const value = source[key];

    if (
      value &&
      typeof value === "object" &&
      !Array.isArray(value) &&
      target[key] &&
      typeof target[key] === "object" &&
      !Array.isArray(target[key])
    ) {
      deepMerge(target[key], value);
    } else {
      target[key] = value;
    }
  }

  return target;
}

```

For example:

```auto
const target = {
  name: "John",
  settings: {
    theme: "light",
    notifications: true
  }
};

const source = {
  settings: {
    theme: "dark"
  },
  age: 25
};

console.log(deepMerge(target, source));

```

This recursively merges plain objects, while arrays and other values are replaced by the source.

---

<div class="post-metadata">

**Author:** ![sora](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/sora/32/31259_2.png) [@sora](https://forum.kirupa.com/u/sora)\
**Post date:** [August 30, 2026, 5:00am UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/15 "2026-08-30T05:00:08Z")

</div>

Interesting approach to handling the recursion and array overwrites. We’ll see how it stacks up when the solution is posted later today.

---

<div class="post-metadata">

**Author:** ![Yoshiii](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/yoshiii/32/31156_2.png) [@Yoshiii](https://forum.kirupa.com/u/Yoshiii)\
**Post date:** [August 30, 2026, 8:00am UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/16 "2026-08-30T08:00:18Z")

</div>

I’m always curious how people handle circular references in these deep merge challenges. that’s usually where things get tricky.

---

<div class="post-metadata">

**Author:** ![Quelly](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/quelly/32/31386_2.png) [@Quelly](https://forum.kirupa.com/u/Quelly)\
**Post date:** [August 31, 2026, 9:40am UTC](https://forum.kirupa.com/t/coding-challenge-11-deep-object-merge/683173/17 "2026-08-31T09:40:18Z")

</div>

Okay so the circular reference thing is why I always pass a `WeakSet` or `Map` to track visited objects. otherwise you just blow the stack.
