A bingo caller is the machine that draws numbers, says them out loud, and shows them on a board. I needed one for BingWow , a free bingo site. The obvious build is a server that owns the deck and a SpeechSynthesis call for the voice. I shipped neither. Here is why, and what the no-backend version actually looks like. You can play with the result here: bingwow.com/caller . It runs entirely in the tab. The state lives in a reducer, not a server A multiplayer bingo board needs a server, because two players must agree on who claimed what. A caller does not. One person runs it, on one screen, and reads numbers to a room. There is nothing to synchronize. So the whole game is a useReducer : interface CallerState { mode : BallMode ; // '30' | '75' | '90' deck : number []; // shuffled, pop() to draw called : BingoBall []; calledSet : Set < number > ; // O(1) "was this called" isAutoMode : boolean ; roundNumber : number ; } case ' DRAW ' : { if ( state . deck . length === 0 ) return state ; const deck = [...…