How to calculate the factorial of a number in JavaScript
Calculating factorials is essential for combinatorics, probability, permutation generators, and statistical analysis in JavaScript applications. With over 25 years of experience in software development and as the creator of CoreUI, I’ve implemented factorial calculations in mathematical utilities, educational tools, and data analysis features. Factorial is only defined for non-negative integers — always validate input before computing.
Use iteration or recursion to calculate n! (n factorial), the product of all positive integers up to n.
factorialIterative(5) // 120
factorialIterative(0) // 1
factorialIterative(-1) // throws RangeError
1. Input Validation
Factorial is undefined for negative numbers and non-integers. Both implementations below throw early for invalid input — use Number.isNaN() to catch non-numeric inputs upstream.
function validateFactorialInput(n) {
if (typeof n !== 'number' || !Number.isFinite(n)) {
throw new TypeError('Input must be a finite number')
}
if (!Number.isInteger(n)) {
throw new TypeError('Input must be an integer')
}
if (n < 0) {
throw new RangeError('Factorial is not defined for negative numbers')
}
}
2. Iterative Approach
Iteration is preferred for production code — it avoids call stack growth and is safe for any valid input.
function factorialIterative(n) {
validateFactorialInput(n)
let result = 1
for (let i = 2; i <= n; i++) {
result *= i
}
return result
}
factorialIterative(0) // 1 (0! = 1 by definition)
factorialIterative(5) // 120
factorialIterative(10) // 3628800
factorialIterative(20) // 2432902008176640000 (safe integer limit)
Note: Number.MAX_SAFE_INTEGER is 2^53 - 1. For n >= 21, the result exceeds this and precision is lost — see the BigInt section below.
3. Recursive Approach
Recursion mirrors the mathematical definition n! = n × (n−1)! and is readable for educational purposes.
function factorialRecursive(n) {
validateFactorialInput(n)
if (n <= 1) return 1
return n * factorialRecursive(n - 1)
}
factorialRecursive(5) // 120
factorialRecursive(10) // 3628800
Caution: Each recursive call adds a stack frame. For large n (typically above ~10,000), this throws a RangeError: Maximum call stack size exceeded. Use iteration for production.
4. BigInt for Large Numbers
JavaScript’s number type loses precision above n = 20. Use BigInt when you need exact results for larger factorials.
function factorialBigInt(n) {
validateFactorialInput(n)
let result = 1n
for (let i = 2n; i <= BigInt(n); i++) {
result *= i
}
return result
}
factorialBigInt(20) // 2432902008176640000n (exact)
factorialBigInt(21) // 51090942171709440000n (would be imprecise as number)
factorialBigInt(50) // 30414093201713378043612608166979581188299763898377856000000000000n
BigInt arithmetic is exact but slower than regular number arithmetic. Use it only when precision matters and n may exceed 20.
5. Memoized Factorial
If you call factorial repeatedly with the same inputs (e.g. in a permutation calculator), cache results to avoid redundant work.
const factorialCache = new Map()
function factorialMemo(n) {
validateFactorialInput(n)
if (n <= 1) return 1
if (factorialCache.has(n)) return factorialCache.get(n)
const result = n * factorialMemo(n - 1)
factorialCache.set(n, result)
return result
}
factorialMemo(10) // 3628800 — computed
factorialMemo(10) // 3628800 — from cache
Memoization pays off when computing factorials for a range of values, such as building a lookup table for binomial coefficients.
Best Practice Note:
Always validate input — negative numbers and non-integers are silent bugs waiting to happen.
Use the iterative approach for production code and switch to BigInt when n may exceed 20.
Memoization is worth the overhead in combinatorics workloads where the same values are needed repeatedly.



