Stack Overflow in JavaScript: Causes and Fixes
Unbounded recursion blows up the call stack. Here is why it happens and how to fix or avoid it.
Stack Overflow in JavaScript: Causes and Fixes
A stack overflow happens when the call stack exceeds its maximum size. In JS, the most common cause is unbounded recursion.
Why the Stack Is Finite
Each function call pushes a frame holding arguments, locals, and the return address. The engine allocates a fixed amount of memory for the stack. When frames pile up past that limit, the engine throws RangeError: Maximum call stack size exceeded.
Common Causes
- No base case in recursion:
function recurse() { recurse(); } recurse(); // RangeError
- Mutual recursion that never terminates:
function a() { b(); } function b() { a(); } a(); // RangeError
- Accidental self-call:
function setValue(obj) { obj.value = setValue(obj); // meant to call a helper }
How to Fix
- Add a base case: every recursive function needs a condition that stops the recursion.
function factorial(n) { if (n <= 1) return 1; // base case return n * factorial(n - 1); }
- Use iteration for cases that do not need recursion. A loop uses constant stack space.
- Use tail call optimization where supported (rare in practice; not in V8).
- Use trampolines for deep recursion in functional code: wrap recursive returns in thunks and run them in a loop.
Stack Limits Vary
Engines and environments have different limits. Browsers often allow 10,000-20,000 frames. Node.js allows similar. Do not write code that depends on a specific limit.
The Takeaway
Stack overflow is caused by frames piling up past the engine's limit. The fix is a base case for recursion, or converting to an iterative approach. Never rely on a specific stack depth, since limits vary across engines.
Unbounded or very deep recursion. Each call adds a frame to the call stack without popping one, until the engine's maximum stack size is exceeded and a RangeError is thrown.
RangeError: Maximum call stack size exceeded. It is thrown when the call stack hits the engine's allocated limit.
Always include a base case that stops the recursion. For deep recursion that cannot be bounded, convert to an iterative loop or use a trampoline to run recursive steps without growing the stack.
It varies by engine and environment, typically 10,000-20,000 frames in browsers and Node.js. Do not write code that depends on a specific limit.
The ES6 spec includes tail call optimization, but most engines (including V8) do not implement it. In practice, deep recursion still overflows the stack and should be converted to iteration.
Ready to master React completely?
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.
Master React
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course.

