How do you implement a Stack and a Queue in JavaScript?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Stacks and queues look similar because both store items in sequence, but they enforce different removal rules. A stack is last in, first out. A queue is first in, first out. That difference drives both the API and the implementation.
In JavaScript, the simplest stack uses an array. A queue can also start with an array, but if you care about predictable performance, it is better to avoid shift() and track the front of the queue explicitly.
Implement a Stack with an Array
Arrays are a natural fit for stacks because push() and pop() operate at the end.
This is enough for most stack use cases, including undo logic, expression parsing, and depth-first traversal. The core idea is that insertion and removal happen at the same end of the structure.
Implement a Queue Without shift()
The obvious queue implementation is push() plus shift(). It works, but shift() has to move the remaining elements down, which makes it a poor choice when the queue gets large or when enqueue and dequeue happen frequently.
A better queue tracks head and tail indexes:
This version keeps queue operations simple even when the queue grows, because removing the front element does not require reshaping the whole collection.
Choose the Simpler Form Only When It Is Enough
For a short script or interview warm-up, an array queue may still be acceptable:
The issue is not correctness. It is cost. For tiny workloads, the simple version is fine. For repeated queue traffic, the indexed version is a better baseline.
That distinction is useful in interviews and real code. It shows that you understand both the abstract data structure and the behavior of the underlying JavaScript operations.
Common Pitfalls
The biggest mistake is treating a queue exactly like a stack because both use "add" and "remove" operations. The ordering rule is the whole point of the structure, so the API should make that rule obvious with names such as enqueue and dequeue.
Another common issue is implementing a queue with shift() without thinking about the cost of repeated front removals.
It is also easy to return special strings such as "Underflow" when the structure is empty. In JavaScript, returning undefined is usually the simpler and more natural empty-result value.
Finally, if code outside the class manipulates the backing storage directly, the stack or queue abstraction stops protecting the ordering behavior that made it useful.
Summary
- Use an array-backed class for stacks with
push()andpop(). - For queues, prefer head and tail indexes when performance matters.
- Keep the operations explicit:
push,pop,peek,enqueue,dequeue, andfront. - Use the simplest implementation that matches the workload.
- Preserve the abstraction so the rest of the program cannot break the ordering rules accidentally.
Related reading
- How do you know where to perform rotations in an AVL tree?
- How do you partition an array into 2 parts such that the two parts have equal average?
- How do you read a file into a list in Python?
- How do you remove a queue binding from RabbitMQ?
- How do you keep parents of floated elements from collapsing?
- How do you prevent install of devDependencies NPM modules for Node.js (package.json)?
- How do you rotate a two dimensional array?
- How do you sort a dictionary by value?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.