Math.random()
Returns a pseudo-random floating-point number in the range 0 (inclusive) to 1 (exclusive).
Math.random()- Added in JavaScript ES1
Return value
numberA floating-point pseudo-random number greater than or equal to 0 and less than 1, with approximately uniform distribution over that range.
Math.random() takes no arguments and returns a float in [0, 1) — zero is possible, one never is. Every other random value you need is built by scaling that.
When to reach for it
Sampling, shuffling, jitter on retry delays, picking a placeholder, seeding a simulation. It is fine for anything where a biased or predictable result is merely annoying.
What trips people up
It is not cryptographically secure. The spec makes no guarantee about the quality of the sequence and the seed is chosen by the engine — you cannot set or reset it. Never use it for tokens, passwords, session IDs, or anything an attacker benefits from predicting; use crypto.getRandomValues() or crypto.randomUUID().
The second trap is off-by-one in integer ranges. For an inclusive range use Math.floor(Math.random() * (max - min + 1)) + min. Using Math.round() instead of Math.floor() is a real bug: it makes the two endpoints half as likely as every interior value.
The third is shuffling with sort(() => Math.random() - 0.5). That comparator is inconsistent, so the permutation is heavily biased and depends on the engine's sort algorithm. Use a Fisher-Yates shuffle.
Finally, there is no way to seed it. Tests that need reproducible randomness must supply their own PRNG.
Example
When to use it
- Picking a random element from an array
- Rolling dice or generating an integer in an inclusive range
- Adding jitter to a retry backoff delay
- Shuffling a deck or playlist with Fisher-Yates
Frequently asked questions
How do I get a random integer between two numbers in JavaScript?
Use Math.floor(Math.random() * (max - min + 1)) + min for a range inclusive of both ends. Use Math.floor rather than Math.round, which makes the endpoints half as likely as the interior values.
Is Math.random() secure enough for tokens or passwords?
No. The specification makes no guarantee about the sequence's unpredictability, so use crypto.getRandomValues() or crypto.randomUUID() for anything security-sensitive.
Can I seed Math.random() for reproducible tests?
No — the seed is chosen by the engine and cannot be set or reset. Implement a small seeded PRNG such as mulberry32 or xorshift when you need repeatable sequences.
More examples
Why round() biases an integer range
With floor, each of the three buckets covers an equal third of [0, 1). With round, the outer buckets only cover a quarter of the range each while the middle covers a half, so 2 comes up about twice as often as 1 or 3. Exact counts vary per run; the shape does not.
const counts = { floor: {}, round: {} };
for (let i = 0; i < 60000; i++) {
const f = Math.floor(Math.random() * 3) + 1; // 1..3
const g = Math.round(Math.random() * 2) + 1; // 1..3, biased
counts.floor[f] = (counts.floor[f] ?? 0) + 1;
counts.round[g] = (counts.round[g] ?? 0) + 1;
}
console.log("floor:", counts.floor); // roughly 20000 each
console.log("round:", counts.round); // 1 and 3 about half as commonFisher-Yates shuffle
Each pass picks uniformly from the not-yet-placed portion, which makes every permutation equally likely. The two shuffled outputs differ each run while the source array is untouched. sort(() => Math.random() - 0.5) looks equivalent but produces a measurably skewed distribution.
function shuffle(arr) {
const a = [...arr];
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
const deck = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(shuffle(deck));
console.log(shuffle(deck));
console.log(deck); // unchanged — the original is copied
Discussion