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.
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:
// 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:
// RIGHT: update expression increments i
for (let i = 0; i < 5; i++) {
console.log(i);
}
// Prints: 0, 1, 2, 3, 4The 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:
// 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.
// 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?
| Condition | Counter Must | Wrong Direction Looks Like |
|---|---|---|
| i > 0 | Decrease | Counting up while checking greater-than-zero |
| i < 100 | Increase | Counting 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:
// 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.
// RIGHT: counter increments inside the body
let count = 0;
while (count < 5) {
console.log(count);
count++;
}
// Prints: 0, 1, 2, 3, 4continue 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:
// 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:
// RIGHT: counter updates before continue
let i = 0;
while (i < 5) {
i++;
if (i === 3) {
continue;
}
console.log(i);
}
// Prints: 1, 2, 4, 5This 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:
// 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.
// 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 exitsFloating-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:
// 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:
// 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:
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 Type | What to Check |
|---|---|
| for | Update expression exists and moves counter toward condition boundary |
| for | Condition uses < / > not === / !== with floating-point |
| while | Counter is updated inside the body on every path |
| while | Counter update comes before any continue |
| do while | Same as while, plus verify condition can eventually be false |
| All | Safety counter during development |
Quick Reference: Most Common Causes
-
Missing increment in a for loop header.
-
Counter update after continue in a while loop.
-
Condition uses wrong comparison direction (counting up but checking greater-than, or vice versa).
-
Floating-point exact comparison (equality checks with decimal increments).
-
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
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.
Frequently Asked Questions
What happens when JavaScript hits an infinite loop?
How can I recover from an infinite loop during development?
Is there a way to set a maximum number of iterations?
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.
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.