Remote Income Hub

How to Generate a Random Number in a Range in JavaScript

Generating random numbers within a specific range is one of those tasks that looks simple on the surface but has enough edge cases to catch you out if you do not understand what is happening underneath. JavaScript’s built-in Math.random() gives you a starting point, but it takes a small amount of math to make it useful for real-world scenarios.

This guide covers everything from the basics to a production-ready utility you can drop into any project.

How Math.random() Works

Math.random() returns a floating-point number between 0 (inclusive) and 1 (exclusive). That means it can return 0 but never exactly 1.

console.log(Math.random()); // 0.7364829461
console.log(Math.random()); // 0.1284736251
console.log(Math.random()); // 0.9873621048

On its own, a number between 0 and 1 is rarely what you need. You almost always want a number within a specific range — between 1 and 10, between 50 and 100, between -5 and 5.

That is where the range formula comes in.

Random Float Between Two Numbers

To generate a random decimal number between a minimum and maximum value:

function randomFloat(min, max) {
  return Math.random() * (max - min) + min;
}

console.log(randomFloat(1, 10));   // 7.382947162
console.log(randomFloat(0, 100)); // 63.91847263
console.log(randomFloat(5, 6));   // 5.748291736

Here is the math explained:

So randomFloat(5, 10) gives you a number from 5 up to (but not including) 10.

Random Integer Between Two Numbers (Inclusive)

Floats are rarely what you want when you need a random number in a range. Most of the time you want a whole number — a random index, a dice roll, a random ID, a random item picker.

To get a random integer where both the minimum and maximum are included in the possible results:

function randomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

console.log(randomInt(1, 6));    // Simulates a dice roll: 1, 2, 3, 4, 5, or 6
console.log(randomInt(0, 100)); // 0 to 100 inclusive
console.log(randomInt(10, 20)); // 10 to 20 inclusive

Breaking down the formula:

The + 1 is what makes the maximum inclusive. Without it, max would never be reachable.

Random Integer Excluding the Maximum

Sometimes you want the maximum to be exclusive — like when generating a random array index, where the valid range is 0 to array.length - 1:

function randomIntExclusive(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
}

// Random array index
const colors = ["red", "green", "blue", "yellow"];
const index = randomIntExclusive(0, colors.length); // 0, 1, 2, or 3
console.log(colors[index]);

This is the MDN-recommended formula for array index generation. The + 1 is removed so max itself is never returned.

Practical Examples

Simulating a Dice Roll

function rollDice(sides = 6) {
  return randomInt(1, sides);
}

console.log(rollDice());    // 1–6
console.log(rollDice(20));  // 1–20 for a D20

Picking a Random Item From an Array

function randomItem(array) {
  const index = Math.floor(Math.random() * array.length);
  return array[index];
}

const fruits = ["apple", "banana", "cherry", "mango"];
console.log(randomItem(fruits)); // One of the four fruits

Generating a Random Color

function randomColor() {
  const r = randomInt(0, 255);
  const g = randomInt(0, 255);
  const b = randomInt(0, 255);
  return `rgb(${r}, ${g}, ${b})`;
}

console.log(randomColor()); // "rgb(142, 87, 213)"

Random Hex Color

function randomHexColor() {
  return "#" + Math.floor(Math.random() * 0xFFFFFF)
    .toString(16)
    .padStart(6, "0");
}

console.log(randomHexColor()); // "#a3f2c1"

Shuffling an Array (Fisher-Yates Algorithm)

Generating random numbers in a range is the foundation of array shuffling:

function shuffle(array) {
  const arr = [...array]; // Don't mutate the original
  for (let i = arr.length - 1; i > 0; i--) {
    const j = randomInt(0, i);
    [arr[i], arr[j]] = [arr[j], arr[i]];
  }
  return arr;
}

const deck = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(shuffle(deck)); // [4, 7, 1, 8, 3, 6, 2, 5]

Generating Multiple Random Numbers

To generate an array of random integers:

function randomInts(count, min, max) {
  return Array.from({ length: count }, () => randomInt(min, max));
}

console.log(randomInts(5, 1, 100)); // [42, 7, 88, 23, 61]
console.log(randomInts(3, 1, 6));   // [3, 5, 1]

Array.from({ length: count }) creates an array of the specified size and the callback populates each slot with a random integer.

Generating Unique Random Numbers

If you need a set of unique random numbers — like lottery numbers or a hand of cards — generate and filter with a Set:

function uniqueRandomInts(count, min, max) {
  const results = new Set();
  while (results.size < count) {
    results.add(randomInt(min, max));
  }
  return [...results];
}

// 6 unique numbers from 1 to 49 (like a lottery)
console.log(uniqueRandomInts(6, 1, 49)); // [12, 7, 34, 19, 47, 3]

Note: this function will loop infinitely if you ask for more unique numbers than the range can provide. Add a guard if your inputs are user-controlled:

function uniqueRandomInts(count, min, max) {
  const rangeSize = max - min + 1;
  if (count > rangeSize) {
    throw new Error(`Cannot generate ${count} unique numbers in range [${min}, ${max}]`);
  }
  const results = new Set();
  while (results.size < count) {
    results.add(randomInt(min, max));
  }
  return [...results];
}

Seeded Random Numbers

Math.random() is not seedable in JavaScript — you cannot reproduce the same sequence by providing a starting value. If you need reproducible random numbers (for testing, procedural generation, or simulations), you need a seeded pseudo-random number generator.

A simple seeded PRNG using a linear congruential generator:

function createSeededRandom(seed) {
  let s = seed;
  return function() {
    s = (s * 1664525 + 1013904223) % 4294967296;
    return s / 4294967296;
  };
}

const random = createSeededRandom(42);
console.log(random()); // Always the same sequence for seed 42
console.log(random());
console.log(random());

This returns a function that behaves like Math.random() but produces the same sequence every time for the same seed. You can use it inside randomInt() by replacing Math.random() with your seeded function.

For more robust seeding, libraries like seedrandom provide well-tested implementations.

Cryptographically Secure Random Numbers

Math.random() is not cryptographically secure. It is fine for games, UI randomization, and general use — but not for security-sensitive applications like generating tokens, passwords, or keys.

For cryptographically secure random numbers in the browser or Node.js:

// Browser and modern Node.js
function secureRandomInt(min, max) {
  const range = max - min + 1;
  const bytesNeeded = Math.ceil(Math.log2(range) / 8);
  const maxValid = Math.floor(256 ** bytesNeeded / range) * range;

  let value;
  do {
    const bytes = crypto.getRandomValues(new Uint8Array(bytesNeeded));
    value = bytes.reduce((acc, byte, i) => acc + byte * 256 ** i, 0);
  } while (value >= maxValid);

  return min + (value % range);
}

console.log(secureRandomInt(1, 100));

For most use cases, Math.random() is perfectly adequate. Use crypto.getRandomValues() when the randomness is for authentication, security tokens, or anything where predictability would be a vulnerability.

The Complete Utility Reference

// Float between min (inclusive) and max (exclusive)
function randomFloat(min, max) {
  return Math.random() * (max - min) + min;
}

// Integer between min and max (both inclusive)
function randomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

// Integer between min (inclusive) and max (exclusive)
function randomIntExclusive(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
}

// Random item from array
function randomItem(array) {
  return array[Math.floor(Math.random() * array.length)];
}

// Array of random integers
function randomInts(count, min, max) {
  return Array.from({ length: count }, () => randomInt(min, max));
}

// Array of unique random integers
function uniqueRandomInts(count, min, max) {
  const rangeSize = max - min + 1;
  if (count > rangeSize) throw new Error("Range too small for requested count");
  const results = new Set();
  while (results.size < count) results.add(randomInt(min, max));
  return [...results];
}

Tips for Working With Random Numbers in JavaScript

Use randomInt() for array indexes. When picking a random element from an array, use the exclusive version — randomIntExclusive(0, array.length) — so the index is always valid.

Do not use Math.random() for security. Tokens, session IDs, passwords, and keys need crypto.getRandomValues() instead.

Test edge cases with a range of 1. When min and max are the same, your function should return that value every time. Make sure yours does.

Seed random numbers for reproducible tests. If unit tests rely on random behavior, a seeded PRNG ensures consistent, repeatable results.

Math.random() is not truly random. It is a pseudo-random number generator — the sequence is deterministic but unpredictable for practical purposes. For games, UIs, and data generation, it is more than sufficient…..

Generating a random number in a range in JavaScript starts with Math.random() and a small formula to scale and shift the output. For integers, Math.floor(Math.random() * (max - min + 1)) + min gives you both endpoints inclusive. For floats, Math.random() * (max - min) + min does the job.

Build the two or three utility functions you need, test the edge cases, and use crypto.getRandomValues() whenever the randomness matters for security. Everything else is just calling the right function with the right range.

Exit mobile version