Question

How to Add Elements to the Beginning of an Array in JavaScript

Question

I need to add, or prepend, an element to the beginning of a JavaScript array.

For example, if the array is:

[23, 45, 12, 67]

and the response from an AJAX call is 34, I want the updated array to become:

[34, 23, 45, 12, 67]

Right now, I am considering this approach:

var newArray = [];
newArray.push(response);

for (var i = 0; i < theArray.length; i++) {
    newArray.push(theArray[i]);
}

theArray = newArray;

Is there a better way to do this? Does JavaScript provide a built-in method for adding elements to the beginning of an array?

Also, since my current approach is O(n), I would be interested in understanding whether there are better implementations and what their trade-offs are.

Short Answer

By the end of this page, you will understand how to add elements to the beginning of a JavaScript array, when to use unshift(), how it compares with alternatives like spread syntax and concat(), and why prepending to arrays usually remains an O(n) operation.

Concept

In JavaScript, arrays have built-in methods for adding and removing elements. When you want to place a new value at the start of an array, the standard built-in method is unshift().

const arr = [23, 45, 12, 67];
arr.unshift(34);
console.log(arr); // [34, 23, 45, 12, 67]

This matters because adding to the beginning of an array is a very common operation in real applications:

  • showing newest notifications first
  • adding recent messages to a feed
  • maintaining a list of latest results
  • inserting priority items at the front

However, there is an important performance idea behind this: JavaScript arrays are index-based. If you insert an item at index 0, the existing items usually need to shift one position to the right.

For example:

  • 23 moves from index 0 to 1
  • 45 moves from index 1 to 2
  • 12 moves from index 2 to 3
  • 67 moves from index 3 to 4

That is why prepending is typically O(n). Your manual loop is also O(n), and so is unshift() in the general case. The main improvement from using unshift() is clarity, correctness, and convenience, not a lower time complexity.

If you need a new array without mutating the original one, you can also use:

const newArr = [34, ...arr];

or:

const newArr = [34].concat(arr);

So the key idea is:

  • use unshift() when you want to modify the existing array
  • use spread syntax or concat() when you want a new array
  • expect prepending to still be O(n) for normal arrays

Mental Model

Think of a JavaScript array like a row of numbered lockers:

  • locker 0 contains 23
  • locker 1 contains 45
  • locker 2 contains 12
  • locker 3 contains 67

If you want to put 34 into locker 0, the current contents cannot stay where they are. Every existing item must move one locker to the right.

So prepending is like inserting a new person at the front of a line: everyone already in line has to step back one position.

That is why adding at the beginning is more work than adding at the end. Appending with push() is usually easier because no existing elements need to move.

Take Quiz

Syntax and Examples

The most direct built-in method is unshift().

array.unshift(element1, element2, ...)

It adds one or more elements to the beginning of an array and returns the new length.

Basic example

const numbers = [23, 45, 12, 67];
const newLength = numbers.unshift(34);

console.log(numbers);   // [34, 23, 45, 12, 67]
console.log(newLength); // 5

Explanation:

  • unshift(34) inserts 34 at the start
  • the original array is modified
  • the method returns the array's new length

Add multiple elements

const numbers = [23, 45, 12, 67];
numbers.unshift(1, 2, 3);

console.log(numbers); // [1, 2, 3, 23, 45, 12, 67]

Create a new array instead of mutating

Using spread syntax:

const original = [23, 45, 12, 67];
const updated = [34, ...original];

console.log(original); // [23, 45, 12, 67]
console.log(updated);  // [34, 23, 45, 12, 67]

Using concat():

const original = [23, 45, 12, 67];
const updated = [34].concat(original);

console.log(updated); // [34, 23, 45, 12, 67]

Which one should beginners remember?

  • unshift() → modify the existing array
  • [value, ...array] → create a new array
  • [value].concat(array) → older but still valid alternative

Step by Step Execution

Consider this example:

const arr = [23, 45, 12, 67];
arr.unshift(34);
console.log(arr);

Here is what happens step by step:

Step 1: Create the array

const arr = [23, 45, 12, 67];

Memory conceptually looks like this:

IndexValue
023
145
212
367

Step 2: Call unshift(34)

arr.unshift(34);

JavaScript inserts 34 at index 0.

To make room, the existing elements shift right:

  • 67 moves from 3 to 4
  • 12 moves from 2 to 3
  • 45 moves from 1 to 2
  • 23 moves from 0 to 1
  • 34 is placed at 0

Now the array becomes:

IndexValue
034
123
245
312
467

Step 3: Print the result

console.log(arr);

Output:

[34, 23, 45, 12, 67]

Trace with return value

const arr = [23, 45, 12, 67];
const length = arr.unshift(34);

console.log(length); // 5
console.log(arr);    // [34, 23, 45, 12, 67]

unshift() returns the new length, not the updated array.

Real World Use Cases

Prepending values to arrays appears in many common situations.

Activity feeds

A new notification arrives and should appear first:

const notifications = ["Older alert", "Yesterday's alert"];
notifications.unshift("New alert");

Chat applications

If messages are displayed with newest first, a newly received message may be inserted at the front:

const messages = ["How are you?", "Hello"];
messages.unshift("Latest message");

Search history

Recent searches are often shown first:

const searches = ["javascript map", "css grid"];
searches.unshift("array unshift");

Logging and monitoring dashboards

Incoming events may be added to the start of a list so the most recent issue is visible immediately.

Data processing scripts

You may prepend a header row or a high-priority item before processing a list.

const tasks = ["email report", "clean temp files"];
tasks.unshift("restart server");
Take Quiz

Real Codebase Usage

In real projects, developers choose between mutating and non-mutating approaches depending on the situation.

1. Direct mutation with unshift()

Common in simple scripts or local state where changing the original array is fine.

queue.unshift(newItem);

Use this when:

  • you own the array
  • mutation is acceptable
  • you want the simplest built-in method

2. Immutable update with spread syntax

Very common in React, Redux, and other state-management patterns.

const updatedItems = [newItem, ...items];

Use this when:

  • you should not mutate existing state
  • change detection depends on a new array reference
  • you want predictable state updates

3. Guard clauses before prepending

Developers often validate data first.

if (response == null) {
  return;
}

items.unshift(response);

This prevents invalid values from being inserted.

4. Keeping arrays limited in size

A common pattern is prepend, then trim.

logs.unshift(newLog);
if (logs.length > 100) {
  logs.pop();
}

This keeps only the latest 100 entries.

5. Combining with API results

async function addLatestUser(users) {
  const response = await fetch("/api/latest-user");
  const user = await response.json();
  users.unshift(user);
}

In codebases, the main decision is usually not whether unshift() exists, but whether the array should be mutated or copied.

Common Mistakes

Here are common beginner mistakes when adding elements to the beginning of an array.

Mistake 1: Expecting unshift() to return the array

Broken code:

const arr = [23, 45];
const result = arr.unshift(34);

console.log(result); // 3, not [34, 23, 45]

Why it happens:

  • unshift() returns the new length
  • it does not return the updated array

Correct version:

const arr = [23, 45];
arr.unshift(34);
console.log(arr); // [34, 23, 45]

Mistake 2: Mutating an array when you wanted a new one

Broken code:

const original = [23, 45];
const alias = original;
alias.unshift(34);

console.log(original); // [34, 23, 45]

Why it happens:

  • alias and original point to the same array

Correct version:

const original = [23, 45];
const updated = [34, ...original];

console.log(original); // [23, 45]
console.log(updated);  // [34, 23, 45]

Mistake 3: Using push() instead of unshift()

Broken code:

const arr = [23, 45, 12, 67];
arr.push(34);
console.log(arr); // [23, 45, 12, 67, 34]

Why it happens:

  • push() adds to the end, not the beginning

Correct version:

arr.unshift(34);

Mistake 4: Trying to beat O(n) with a normal array prepend

Many beginners assume there must be a constant-time trick for normal arrays. In standard JavaScript arrays, prepending generally still requires shifting items, so it is usually O(n).

Mistake 5: Writing unnecessary cleanup code

Code like this is not needed:

delete newArray;

Why:

  • delete is not how you normally remove local variables
  • JavaScript uses garbage collection
  • local variables go away when they are no longer referenced

Comparisons

Here is how the main options compare.

ApproachMutates original array?ReturnsTypical use
unshift(value)YesNew lengthSimple in-place prepend
[value, ...array]NoNew arrayImmutable updates
[value].concat(array)NoNew arrayOlder non-mutating style
Manual loopUsually no, unless assigned backDepends on codeRarely needed for this task

unshift() vs push()

MethodAdds where?Mutates?
unshift()BeginningYes
push()EndYes

unshift() vs spread syntax

const arr = [23, 45];
arr.unshift(34);      // arr becomes [34, 23, 45]
const arr = [23, 45];
const updated = [34, ...arr]; // arr unchanged

Choose unshift() when changing the same array is fine. Choose spread syntax when you want to preserve the original array.

Complexity note

All common prepend approaches for standard arrays are effectively O(n) because existing elements need to move or be copied.

Take Quiz

Cheat Sheet

// Mutating prepend
arr.unshift(value);

// Mutating prepend of multiple values
arr.unshift(v1, v2, v3);

// Non-mutating prepend with spread
const updated = [value, ...arr];

// Non-mutating prepend with concat
const updated = [value].concat(arr);

Key rules

  • unshift() adds elements to the start of an array
  • unshift() mutates the array
  • unshift() returns the new length
  • push() adds to the end, not the beginning
  • Prepending to a normal array is usually O(n)

Quick examples

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

Edge cases

  • arr.unshift() with no arguments changes nothing
  • unshift(undefined) adds undefined as a real element
  • multiple arguments keep their order:
const arr = [3, 4];
arr.unshift(1, 2);
console.log(arr); // [1, 2, 3, 4]

FAQ

Is there a built-in JavaScript method to add an item to the beginning of an array?

Yes. Use array.unshift(value).

Does unshift() change the original array?

Yes. unshift() mutates the existing array.

What does unshift() return in JavaScript?

It returns the new length of the array, not the array itself.

How do I prepend without modifying the original array?

Use spread syntax or concat():

const updated = [value, ...original];

Is prepending to a JavaScript array O(1)?

Usually no. It is generally O(n) because existing elements need to shift or be copied.

Can I add multiple elements to the beginning at once?

Yes.

arr.unshift(1, 2, 3);

Should I use unshift() in React state updates?

Usually no, because React state should be treated as immutable. Prefer:

setItems([newItem, ...items]);

Is a manual loop ever necessary for prepending?

Usually not. Built-in methods like unshift() or non-mutating patterns are clearer and less error-prone.

Take Quiz

Mini Project

Description

Build a small recent-search tracker. Each time a user performs a search, the newest search term should appear at the beginning of the list. This is a practical example of prepending items to an array and limiting the list to a fixed size.

Goal

Create a function that adds a new search term to the beginning of an array and keeps only the 5 most recent searches.

Requirements

  1. Start with an array of existing search terms.
  2. Add each new search term to the beginning of the array.
  3. Keep only the 5 most recent terms.
  4. Ignore empty search strings.
  5. Print the updated list after each insert.
Take Quiz

Keep learning

Related questions

View more