Ship internal tools in hours, not weeks. Real auth, users, jobs, audit logs, and cohesive UI included. Early access $249 $499 → [Get it now]

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.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author