How to Avoid Infinite Loops in JS: Full Tutorial

An infinite loop freezes your program because the exit condition never becomes false. Learn the most common causes, how to spot them, and how to prevent every type of infinite loop in JavaScript.

6 min read

An infinite loop is a loop whose condition never becomes false. Once it starts, it runs forever. In a browser, the tab freezes. In Node.js, the process hangs until you kill it.

Every infinite loop has the same root cause: the condition controlling the loop can never evaluate to false. The fix is always to ensure something inside the loop body -- or in the update expression for a for loop -- moves the condition toward false.

The Classic For-Loop Infinite Loop

The most common infinite loop is a for loop with a missing or broken update expression, which leaves the counter frozen at its starting value forever:

javascriptjavascript
// DANGEROUS: missing i++
for (let i = 0; i < 5;) {
  console.log(i);
}

The semicolons are still there, but the update expression is empty. i stays 0, the condition is always true, and the loop never stops.

The fix is straightforward:

javascriptjavascript
// RIGHT: update expression increments i
for (let i = 0; i < 5; i++) {
  console.log(i);
}
// Prints: 0, 1, 2, 3, 4
Infinite vs correct for loop

The infinite version on the left has no path from body back through an update. The condition is rechecked with the same i value every time, so it stays true forever. The correct version on the right always moves i closer to 5.

Wrong Comparison Direction

Another common for-loop mistake is writing the condition so the counter moves away from the exit:

javascriptjavascript
// DANGEROUS: counts up but checks for < 0
for (let i = 1; i > 0; i++) {
  console.log(i); // 1, 2, 3, 4... forever
}

i starts at 1 and increases, so the condition is always true. The counter is moving in the wrong direction relative to the condition.

javascriptjavascript
// DANGEROUS: counts down but checks for > 10
for (let i = 10; i < 100; i--) {
  console.log(i); // 10, 9, 8... forever
}

Here i decreases, so the condition is always true. The number gets further from the exit, not closer.

To catch this, ask: does the update move the counter toward or away from the boundary in the condition?

ConditionCounter MustWrong Direction Looks Like
i > 0DecreaseCounting up while checking greater-than-zero
i < 100IncreaseCounting down while checking less-than-100

The Missing Counter Update in while

In a for loop, the update runs automatically. In a while loop, you must update the counter yourself. Forgetting to do so is the most common while-loop bug:

javascriptjavascript
// DANGEROUS: count never changes
let count = 0;
while (count < 5) {
  console.log(count);
  // Missing: count++
}

The loop prints 0 forever. Unlike a for loop, a while loop will not help you, since the condition, body, and update are all independent.

javascriptjavascript
// RIGHT: counter increments inside the body
let count = 0;
while (count < 5) {
  console.log(count);
  count++;
}
// Prints: 0, 1, 2, 3, 4

continue Before the Counter Update

This is a subtler trap that combines continue with a missing update. If continue jumps over the counter increment, the loop gets stuck:

javascriptjavascript
// DANGEROUS: continue skips i++
let i = 0;
while (i < 5) {
  if (i === 3) {
    continue; // Jumps back to condition, i stays 3
  }
  console.log(i);
  i++;
}

When i reaches 3, continue runs. It jumps to the condition check, skipping the increment.

The condition is still true, so the loop runs again with i still at 3. It hits continue again, and this repeats forever.

The fix is to increment before the continue:

javascriptjavascript
// RIGHT: counter updates before continue
let i = 0;
while (i < 5) {
  i++;
  if (i === 3) {
    continue;
  }
  console.log(i);
}
// Prints: 1, 2, 4, 5

This is one of the big advantages of for loops: the update step runs regardless of continue. If you use continue in a while loop, always place the counter update before it.

do while with a Never-False Condition

A do while loop guarantees at least one run. But if the condition can never become false, it still loops forever after that first run:

javascriptjavascript
// DANGEROUS: condition is always true
let value = 100;
do {
  console.log(value);
  value = value / 2;
} while (value >= 0);

At first glance this looks safe, since value is halved each time. But value / 2 never reaches 0 or goes negative. It approaches 0 but never equals or passes it, so the condition is always true.

javascriptjavascript
// RIGHT: use a threshold that halving will cross
let value = 100;
do {
  console.log(value);
  value = value / 2;
} while (value > 0.1);
// Eventually value drops below 0.1 and the loop exits

Floating-Point Comparison Traps

Floating-point math can cause infinite loops when a loop condition expects a counter to hit an exact decimal value instead of crossing a threshold:

javascriptjavascript
// DANGEROUS: floating-point may never equal exactly 1.0
for (let x = 0; x !== 1.0; x += 0.1) {
  console.log(x);
}

Due to how floating-point numbers work, x may jump from a value like 0.9999999999999999 straight to 1.0999999999999999 and skip 1.0 entirely, so the exact-equality check never matches. Never use !== or === with floating-point loop counters. Use an inequality comparison instead:

javascriptjavascript
// RIGHT: use an inequality comparison
for (let x = 0; x < 1.0; x += 0.1) {
  console.log(x);
}

The Safety Counter Pattern

During development, add a hard limit to catch accidental infinite loops before they freeze your environment:

javascriptjavascript
const MAX_ITERATIONS = 10000;
let iterations = 0;
 
while (someCondition) {
  iterations++;
  if (iterations > MAX_ITERATIONS) {
    console.error("Safety limit reached: possible infinite loop");
    break;
  }
}

This is not a fix for the underlying bug, but it gives you a stack trace and an error message instead of a frozen tab. Remove or raise the limit in production once you are confident the loop logic is correct.

Checklist: Avoid Infinite Loops

Loop TypeWhat to Check
forUpdate expression exists and moves counter toward condition boundary
forCondition uses < / > not === / !== with floating-point
whileCounter is updated inside the body on every path
whileCounter update comes before any continue
do whileSame as while, plus verify condition can eventually be false
AllSafety counter during development

Quick Reference: Most Common Causes

  1. Missing increment in a for loop header.

  2. Counter update after continue in a while loop.

  3. Condition uses wrong comparison direction (counting up but checking greater-than, or vice versa).

  4. Floating-point exact comparison (equality checks with decimal increments).

  5. Halving or other converging math that never crosses the threshold.

For the proper use of break and continue, see the break statement guide and the continue statement guide. For the full loop reference, see the JavaScript loops overview.

Rune AI

Rune AI

Key Insights

  • An infinite loop occurs when the loop condition can never evaluate to false.
  • In for loops, the most common cause is a missing or incorrect update expression.
  • In while loops, the most common cause is forgetting to update the counter inside the body.
  • Place counter updates before continue statements in while and do while loops.
  • Use a safety counter with a reasonable maximum as a guard during development.
RunePowered by Rune AI

Frequently Asked Questions

What happens when JavaScript hits an infinite loop?

In a browser, the tab freezes and eventually shows an 'unresponsive page' dialog. In Node.js, the process hangs and you must kill it with Ctrl+C. JavaScript is single-threaded, so an infinite loop blocks everything else on the page, including clicks, animations, and network requests.

How can I recover from an infinite loop during development?

In the browser, close the tab or use the task manager (Shift+Esc in Chrome). In Node.js, press Ctrl+C. There is no way to recover programmatically because the event loop is blocked, so no other code can run to intervene.

Is there a way to set a maximum number of iterations?

Yes. You can add a safety counter that increments each iteration and breaks after a safe limit. This is useful during development or when working with data from external sources where you cannot trust the input size.

Conclusion

Infinite loops happen when the exit condition can never become false. The fix is always the same: make sure something inside the loop body changes a value that the condition depends on. For for loops, check the update expression. For while loops, check that the counter increments before any continue. For do while, remember that the body runs first, so a false initial condition still runs once. Add a safety counter during development as a second line of defense.