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.
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.
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:
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:
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:
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:
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:
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:
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:
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:
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:
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?
| Method | Creates new array? | Mutates originals? | Best for |
|---|---|---|---|
concat() | Yes | No | Classic style, chaining |
[...a, ...b] | Yes | No | Modern code, readability |
push(...b) | No | Yes (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:
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:
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:
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
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.
Frequently Asked Questions
Does concat() change the original arrays?
What is the difference between concat() and the spread operator for merging?
Can I merge more than two arrays at once?
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.
More in this topic
JavaScript While Loop Explained: A Complete Guide
A while loop repeats code as long as a condition stays true. Learn the syntax, see practical examples, and understand when a while loop is the right choice over a for loop.
JavaScript Loops Tutorial: for, while, do while
Loops let JavaScript repeat code without writing it twice. Learn the three core loop types, what each one does, and when to choose one over another.
How to Loop Through Arrays Using JS for Loops Guide
Looping through arrays is the most practical use of JavaScript for loops. Learn how to access each element by index, avoid off-by-one errors, and choose between for, for...of, and forEach.