A bingo caller board has four jobs: draw a number without repeats, say it out loud, mark it on a flashboard, and leave enough history on screen to check a winner. I built that as a browser-only feature for BingWow, because the room already has one host and one screen. There is no shared state worth sending to a server.
The live version is here: bingwow.com/caller. It supports 75-ball, 90-ball, and 30-ball speed bingo, with voice calls and a fullscreen board for a TV or projector.
The caller is local state
A multiplayer bingo game needs a server because every player has an independent board and every tap needs authority. A standalone caller does not. One host runs it. The output is public in the room. Refreshing starts a new game, which is normal for a caller.
The main state is a reducer:
interface CallerState {
mode: BallMode; // '30' | '75' | '90'
deck: number[]; // shuffled, pop() to draw
called: BingoBall[];
calledSet: Set<number>; // O(1) caller-board lookup
isAutoMode: boolean;
roundNumber: number;
}
case 'DRAW': {
if (state.deck.length === 0) return state;
const deck = [...state.deck];
const num = deck.pop()!;
return {
...state,
deck,
called: [...state.called, makeBall(num, state.mode)],
};
}
The caller sends no request when a number is drawn. The deck is shuffled in the tab, the flashboard reads the called set, and the auto-call timer advances only after the current animation has completed.
Why I skipped the Web Speech API
speechSynthesis.speak() looked like the cheap answer. It failed the product test.
The available voices differ by OS and browser. A calm voice on a Mac became a different voice on a Chromebook. Rapid calls also queued badly during auto-call, and traditional 90-ball nicknames sounded flat when a browser voice read them.
The shipped caller uses 331 prerecorded MP3s instead:
- number calls for 30, 75, and 90-ball games
- every traditional 90-ball nickname, from "Legs eleven" to "Two fat ladies"
- welcome, pause, progress, and round-transition clips
- short clips that fit between visual calls at faster speeds
That makes the 90-ball bingo caller sound the same in a classroom, a senior center, a church hall, or a browser tab on a TV.
The flashboard is the product
Most users describe the same surface as a bingo caller board, bingo calling board, or flashboard. The code treats it as a pure display component: it does not own the game; it only renders the current mode and called numbers.
75-ball uses B-I-N-G-O columns. 90-ball and 30-ball use number ranges. The shared caller component seeds the mode from the route:
// /caller defaults to 75-ball
<CallerClient />
// /caller/90-ball
<CallerClient initialMode="90" />
// /caller/30-ball
<CallerClient initialMode="30" />
That gave each mode its own indexable page while keeping one caller implementation. The 90-ball page also includes an interactive list of all 90 traditional calls, built from the same audio manifest used by the caller.
Audio fires from the animation timeline
The drawn ball flies into its cell on the flashboard. The number needs to be spoken at impact, not when React finishes rendering. The first implementation keyed audio from a state effect, and it drifted during auto-call.
The fix was to fire audio from the animation callback:
runFlyingBallToCell({
ball,
targetCell,
onAbsorbed: () => {
setCellRevealed(true);
voiceRef.current?.playBallImpact(ball, mode, lingoEnabled);
},
});
The timeline owns timing, the reducer owns state, and the flashboard stays a pure read model. That split kept manual draw, auto-call, voice mute, and fullscreen mode from fighting each other.
Printing completes the offline game
A free caller alone is only half a bingo night. Players still need cards. The 75-ball caller has a Print Cards flow that generates up to 500 unique cards with validation codes. The support guide is here: Free online bingo caller, and the card printer is here: bingwow.com/print.
The practical setup is simple:
- Open the free caller board.
- Print cards or hand out existing tickets.
- Use fullscreen on a TV or projector.
- Start manual draw or auto-call.
- Check the winner against the call history.
Try the caller
- 75-ball caller board: bingwow.com/caller
- 90-ball UK caller: bingwow.com/caller/90-ball
- 30-ball speed caller: bingwow.com/caller/30-ball
- No-equipment host guide: free online bingo caller
- Bingo night guide: how to host bingo night