Where the randomness comes from
This generator uses crypto.getRandomValues, the browser's cryptographically secure random source, which draws entropy from the operating system. That matters for anything where predictability would be a problem — draws, prizes, security tokens, anything with a stake.
The alternative, Math.random, is a pseudo-random generator seeded once and producing a deterministic sequence. It is fast and entirely adequate for animation jitter or shuffling a demo dataset, and it is not required by the specification to be unpredictable — given enough consecutive outputs, its internal state can be reconstructed and future values predicted.
The distinction is about consequences rather than statistical quality. Both produce sequences that pass casual inspection; only one is safe when someone has an incentive to guess what comes next.
Modulo bias, and how a range is produced correctly
Converting a random number into a range is where implementations quietly go wrong. Taking a remainder — value % n — distributes results unevenly whenever n does not divide the generator's range exactly, because the leftover values at the top of the range map back onto the first few outcomes, making them slightly more likely.
The bias is small for small ranges and grows as the range approaches the generator's own size, but it is real and measurable, and it is the reason a naive dice roll is not quite fair. The correct approach is rejection sampling: discard values falling in the uneven remainder band and draw again, so every outcome has exactly equal probability.
Scaling by multiplication has its own version of the problem, introducing rounding artefacts that make some values more likely than others. Getting a uniform integer range right is genuinely fiddly, which is why using a well-tested implementation matters more than it appears.
What randomness looks like
People are poor judges of random sequences, and consistently reject genuine randomness as insufficiently random. True random output contains clusters, repeats and runs — six coin flips landing the same way happens roughly once in 32 sequences of six, which is common enough to appear regularly and surprising enough to feel wrong.
This is why streaming services deliberately make their shuffle less random than it could be: a genuinely random shuffle plays the same artist consecutively often enough that users report it as broken. The gambler's fallacy is the same misjudgement in the other direction — the belief that a run of one outcome makes the opposite more likely, when independent trials have no memory.
For draws where every entry should be selected once, drawing without replacement is what you want, and a shuffled list is the right structure. For picking a winner from a list, the name wheel handles the presentation; for splitting a group, the team generator handles the constraint.