About this random team generator
A small, dependency-free tool for one job: turning a list of names into a shuffled, size-balanced set of teams. No account, no upload, and nothing you type is stored anywhere.
Why it exists
Picking teams by hand is a small, recurring, mildly awkward chore — a PE teacher splitting a class, a five-a-side organiser drawing sides, a teacher assigning project groups — and it is one of the few decisions where visible fairness matters more than the outcome. A captain's-pick draft is fast to argue with; a shuffled list from a page nobody controls is not. This tool exists to make that draw take five seconds and leave nothing to dispute.
How the split is implemented
Two independent steps, always in this order:
- Shuffle. A standard Fisher–Yates shuffle walks the name list backwards and swaps each position with a uniformly random earlier-or-equal position. This is the same algorithm used any time software needs to produce every possible ordering of a list with equal probability — there is no simpler correct way to do it, and the naive "sort by
Math.random()" approach that some tools use instead is a well-known source of bias. - Partition. The shuffled list is then split by whichever mode is selected: into a fixed number of teams (sizes balanced to within one player, remainder given one-per-team to the first teams rather than dumped on the last one), or into teams of a fixed size (every team gets exactly that many players except the last, which takes the remainder).
The randomness source and the partition functions are plain, DOM-free JavaScript functions with no side effects, which is what let them be unit-tested directly under Node before this page shipped, independent of any browser behaviour.
How it was verified
Before release, the partitioning logic was run against fixed test cases with known, hand-checked answers:
| Input | Mode | Expected sizes | Result |
|---|---|---|---|
| 7 names | 3 teams | 3, 2, 2 | match |
| 10 names | teams of 4 | 4, 4, 2 | match |
| 6 names | 3 teams | 2, 2, 2 | match |
| 3 names | 8 teams (requested) | 1, 1, 1 (capped to 3 teams) | match |
| 3 names | team size 10 | 3 (one team) | match |
Beyond the fixed cases, 500 randomised trials (random roster sizes from 1–40, random team counts and team sizes from 1–10) checked two invariants on every run: every input name appears in the output exactly once — no name dropped, no name duplicated across teams — and, in number-of-teams mode, no two team sizes differ by more than one player. A separate check confirmed the shuffle never drops, adds or duplicates a name, and that it is deterministic when driven by a fixed, injectable random source, which is what makes it testable at all without relying on the browser's own Math.random().
How the site is built
- Static HTML, one small stylesheet, two small scripts. No framework, no build step, no bundler.
- Nothing from the network. No CDN framework, no web font, no remote image; the favicon is an inline SVG data URI. Once the page has loaded it works offline.
- System font stack. Your operating system's own UI font, so nothing downloads and nothing shifts as the page loads.
- Nothing you type is transmitted. The shuffle and the split both happen in your browser; the names you enter are never uploaded anywhere.
- Dark mode follows your system setting via
prefers-color-scheme.
Scope and honesty about limits
This tool balances exactly one thing: team size. It has no concept of skill, seniority, height, experience or any other attribute a real captain might weigh, because a plain text name carries none of that information. If your use case needs skill-balanced teams, sort your roster into tiers first and shuffle each tier separately, or hand-place a few key people before generating the rest.
The randomness is pseudo-random, produced by the browser's Math.random() through a Fisher–Yates shuffle. That is entirely adequate for splitting up a game or a classroom, but it is not a cryptographically secure random number generator, and this tool should not be used to decide anything with money, legal standing or a formal competition ruling attached to the outcome.