How to Merge Two Arrays in JavaScript: Full Guide

Learn three ways to merge arrays in JavaScript: concat(), the spread operator, and push() with spread. Each method has different strengths for different situations.

6 min read

Merging arrays means taking two or more arrays and combining their elements into a single array. JavaScript gives you three ways to do this, and each one behaves a little differently.

The key decision is whether you need a brand new array or want to add elements into an existing one.

1. concat() -- The Classic Method

concat() merges two or more arrays and returns a new array. It does not change any of the original arrays.

javascriptjavascript
const frontend = ["HTML", "CSS", "JavaScript"];
const backend = ["Node.js", "Python", "SQL"];
 
const fullStack = frontend.concat(backend);
 
console.log(fullStack);
// ["HTML", "CSS", "JavaScript", "Node.js", "Python", "SQL"]
console.log(frontend);
// ["HTML", "CSS", "JavaScript"] (unchanged)

The original frontend array is untouched. concat() always builds and returns a brand new array, which is why you have to capture its return value to use the merged result.

concat() also takes multiple arguments at once, so you are not limited to merging just two arrays:

javascriptjavascript
const a = [1, 2];
const b = [3, 4];
const c = [5, 6];
 
const merged = a.concat(b, c);
 
console.log(merged); // [1, 2, 3, 4, 5, 6]

You can even mix individual values in with the arrays you pass, and each value is added as its own element rather than requiring its own array wrapper:

javascriptjavascript
const letters = ["a", "b"];
 
const result = letters.concat("c", ["d", "e"]);
 
console.log(result); // ["a", "b", "c", "d", "e"]

Nested arrays passed to concat() behave differently from individual values. They are flattened only one level deep, so an array of arrays keeps its inner structure intact:

javascriptjavascript
const arr1 = [1, 2];
const arr2 = [[3, 4], [5, 6]];
 
const merged = arr1.concat(arr2);
 
console.log(merged); // [1, 2, [3, 4], [5, 6]]

The inner arrays stay intact rather than merging into the top level. concat() does not deeply flatten, so use flat() afterward if you need a fully flattened result.

2. Spread Operator -- The Modern Way

The spread operator ... expands an array's elements into individual values. You use it inside a new array literal to merge:

javascriptjavascript
const morning = ["coffee", "toast"];
const evening = ["tea", "salad"];
 
const meals = [...morning, ...evening];
 
console.log(meals);  // ["coffee", "toast", "tea", "salad"]
console.log(morning); // ["coffee", "toast"] (unchanged)

Like concat(), the original arrays are not mutated, which makes spread just as safe to use inside functions that should not have side effects on their inputs.

The spread operator also makes it easy to control the exact order the elements end up in, since you simply write the spreads in the order you want them to appear:

javascriptjavascript
const starters = ["soup", "salad"];
const mains = ["steak", "pasta"];
const desserts = ["cake", "ice cream"];
 
const menu = [...starters, ...mains, ...desserts];
 
console.log(menu);
// ["soup", "salad", "steak", "pasta", "cake", "ice cream"]

Writing the same three spreads in a different order produces a completely different array, with no other code changes needed:

javascriptjavascript
const starters = ["soup", "salad"];
const mains = ["steak", "pasta"];
const desserts = ["cake", "ice cream"];
 
const backwards = [...desserts, ...mains, ...starters];
 
console.log(backwards);
// ["cake", "ice cream", "steak", "pasta", "soup", "salad"]

You can also insert individual values between the spreads, mixing single items with entire arrays in whatever order the result needs:

javascriptjavascript
const numbers = [1, 2, 3];
 
const extended = [0, ...numbers, 4, 5];
 
console.log(extended); // [0, 1, 2, 3, 4, 5]

This is cleaner than calling unshift() and push() separately. For a deep dive into the spread operator, see JS Spread Operator for Arrays: Complete Tutorial.

3. push() with Spread -- Merge In Place

If you do not need a new array and want to add all elements from one array into an existing one, use push() with the spread operator:

javascriptjavascript
const allScores = [85, 90];
const newScores = [78, 92, 88];
 
allScores.push(...newScores);
 
console.log(allScores); // [85, 90, 78, 92, 88]

Without the spread, push() would add the entire newScores array as a single nested element instead of merging its individual numbers into the target array:

javascriptjavascript
const allScores = [85, 90];
const newScores = [78, 92, 88];
 
// Wrong: forgets the spread
allScores.push(newScores);
 
console.log(allScores); // [85, 90, [78, 92, 88]]

Always use the spread syntax when you want to add the elements themselves, not the array as a single item.

This method is the most performant for large arrays because it mutates in place without creating an intermediate copy.

Which Method Should You Use?

MethodCreates new array?Mutates originals?Best for
concat()YesNoClassic style, chaining
[...a, ...b]YesNoModern code, readability
push(...b)NoYes (a)Performance, in-place extension

For most everyday code, use the spread operator. It is the most readable and the standard choice in modern JavaScript.

Use push() with spread when you are building up an array inside a loop and want to avoid creating intermediate arrays. Use concat() when chaining with other array methods.

Common Mistakes

Forgetting that concat() returns a new array. Calling concat() on its own and expecting it to change the original array in place is a common mistake, since none of the merge methods in this guide mutate by default except push() with spread:

javascriptjavascript
const a = [1, 2];
const b = [3, 4];
 
a.concat(b);
console.log(a); // [1, 2] (unchanged, the return value was ignored!)
 
const merged = a.concat(b);
console.log(merged); // [1, 2, 3, 4]

Using push() without spread. This mistake goes the opposite direction: forgetting the spread turns the entire second array into one nested element instead of merging its contents:

javascriptjavascript
const a = [1, 2];
const b = [3, 4];
 
a.push(b);
console.log(a); // [1, 2, [3, 4]] (wrong, b was pushed as a single element)

Spreading b fixes it by unpacking each element as its own argument to push(), so every number lands directly in the array instead of one nested array:

javascriptjavascript
const a = [1, 2];
const b = [3, 4];
 
a.push(...b);
console.log(a); // [1, 2, 3, 4]

The spread operator is also the simplest way to create a shallow copy of an array. When you need to copy nested structures, be aware of the difference between shallow and deep copies -- see Copying Nested Objects with the JS Spread Operator.

Rune AI

Rune AI

Key Insights

  • concat() merges arrays into a new array without mutating the originals.
  • The spread operator [...arr1, ...arr2] is the most readable modern way to merge.
  • push(...arr2) merges arr2 into arr1 in place, mutating arr1.
  • concat() and spread create new arrays. push() with spread modifies the existing one.
  • All three methods work with any number of arrays, not just two.
RunePowered by Rune AI

Frequently Asked Questions

Does concat() change the original arrays?

No. concat() returns a new array and leaves the original arrays untouched. Neither the source array nor the arrays passed as arguments are mutated.

What is the difference between concat() and the spread operator for merging?

Both create a new array without mutating the originals. concat() is a method call that accepts multiple arrays as arguments. The spread operator uses ... syntax inside a new array literal. They produce the same result, but spread is more commonly used in modern JavaScript.

Can I merge more than two arrays at once?

Yes. All three methods -- concat(), spread, and push() with spread -- can merge any number of arrays in a single operation.

Conclusion

You have three solid ways to merge arrays in JavaScript. concat() is the classic method that never mutates. The spread operator is the modern, readable choice for most situations. push() with spread is the high-performance option when you need to merge into an existing array without creating a new one. Choose based on whether you need a new array or want to extend an existing one.