Case study - Esportsbook engine

Odds that move while you watch.

A round of Counter-Strike swings a market in seconds, and a sportsbook that shows yesterday's price either cheats the player or eats the loss. We designed and built a live esportsbook that keeps up: a dedicated odds feed, a socket channel per match, markets that understand maps and rounds rather than just winners, and a betslip that reprices selections the player has already added - on screen, with their consent - across roughly twenty-nine titles.

  • live repricing inside the open betslip - accepted, never discovered
  • map-and-round market depth across ~29 esports and sim titles
  • one socket room per match - odds, market states, and scores in real time
Counter-Strike 2 · BLAST PremierLive
Natus Vincere1 - 1Map 2 · 7–5FaZe Clan
AllMatchMap 1Map 2Map 3
Map 2 winner
NaVi1.87
FaZe2.42
Map 2 kills handicap −18.5
Over 18.51.91
Under 18.51.85
Round 13 winner - map 2Suspended
NaVi1.66
FaZe2.10
Client
White-label esportsbook - multi-brand
Sector
iGaming - live esports betting
Role
Product design & frontend engineering, end to end
Engine
Dedicated odds feed · one socket channel per match
Stack
Next.js · React · TypeScript
The challenge

The problem with betting on a game this fast

Esports odds move faster than any price a traditional sportsbook was built to show. A single round of CS2 can flip a map market in seconds; a lost pistol round moves the handicap before a polling cycle comes back. A book that displays stale prices has exactly two outcomes, and both are bad: it honors bets at odds it no longer means, or it rejects them after the fact and teaches the player that the number on screen was never real. Either way the product loses the only thing a betting product has, which is that its prices can be believed.

The second problem is structural. Generic sports engines treat esports as one more sport: a fixture, a winner, maybe a total. But an esports match is maps inside a series and rounds inside a map, and that is where the real market depth lives - first blood on map one, the thirteenth round of map two, a kills handicap at minus 18.5. A book that cannot express that structure offers a fraction of the markets the game supports and reads as tourist software to the audience it is courting. So the brief was both halves at once: prices that move at the game's speed, and markets shaped like the game actually is.

Inside the product

Four screens, one promise

This product ships white-label under brands we can't show, so these panels are drawn - same layout, same states, same numbers the player sees. The player meets the engine in this order: pick a title from the rail, open a match and find its map-and-round depth, build a slip that reprices under their eyes, and watch the round they just bet on without leaving the screen.

TitlesAllLivePast
CS212Dota 28LoL9Valorant6R63RL4SC22+22 more
The title rail: around twenty-nine esports and sim titles behind one row of chips, in a curated order with normalized display names - and a live event count on every title, so the busiest games sit first.
AllMatchMap 1Map 2Map 3
Map 1
First blood - map 1NaVi1.72FaZe2.05
Map kills handicap −16.5 - map 1Over2.02Under1.76
Map kills handicap −18.5 - map 1Over1.91Under1.85
Map 2
Round 13 winner - map 2NaVi1.66FaZe2.10
Map-and-round depth, not just match winner. Markets arrive named like the feed names them - first blood, round 13 winner, kills handicaps - and the engine parses them into per-map groups with handicap lines sorted numerically.
Betslip2
Map 2 winner · NaVi vs FaZe
NaVi1.87
Odds changed · 1.79 → 1.87Accept
Map 2 kills handicap −18.5
Over 18.51.91
Multiple (2)3.57
0.0040ETH
Est. payout0.014287 ETH
Place bet
The live betslip, mid-reprice. Socket updates land inside the open slip: the price on a selection the player already added moves on screen, and the slip asks them to accept the new odds - the player approves a change, never discovers one after settlement. Payouts are computed to six decimals for crypto stakes.
Live · Twitch
Map 2 markets
NaVi1.87
FaZe2.42
Over 18.51.91
Under 18.51.85
The stream beside the markets. The match feed - Twitch preferred, from the fixture's own channels - embeds next to the odds, so watching the round and betting on it is one screen, not two tabs.
What we built

The engine behind the odds

Each piece exists to keep one promise: the price on screen is the price you bet.

01

A dedicated esports feed, not a sportsbook bolt-on

Esports runs on its own odds service, separate from the casino backend: endpoints for live, prematch, past, and paginated matches, single-match detail, and tournaments that carry their own live, prematch, and past event counts. The vertical has a data layer shaped for the game, not a sport slot borrowed from football.

02

One socket room per match

A dedicated socket.io channel carries the live layer; opening a match joins its room, and change events merge straight into application state - odds, market active states, and period scores update in place, only for the matches on screen. Nothing polls, and nothing repaints a page to move a price.

03

A betslip that reprices in place

The same socket events reach selections the player has already added: when a price moves inside the open slip, the slip shows the change and asks the player to accept the new odds before the bet stands. Suspended markets lock their selections, conflicting picks from one market refuse to combine, and stakes are checked against balance - every failure is caught in the slip, not after submission.

04

Markets that understand maps and rounds

The engine parses feed market names - first blood on map one, round 13 winner on map two, kills handicaps with their lines - into per-map groups, filterable by Map 1, 2, 3, the match, or everything at once, with handicap lines sorted numerically. The depth esports actually has, laid out the way a player thinks about the series.

05

Singles and multiples in one slip, exact to the currency

One slip holds single bets and combos side by side, with combo odds and payouts computed in decimal arithmetic - six decimal places for crypto stakes, two for fiat - and submitted as one currency-scoped request that carries the accepted odds changes with it. The number the player saw is the number the book receives.

06

The stream beside the markets

Each fixture carries its own stream channels; the product prefers a Twitch feed and falls back to the first available, embedding the match beside the markets. Watching the round and betting on it is one screen, which for a live product is the whole point.

07

Twenty-nine titles, one switch per brand

The catalog spans roughly twenty-nine esports and sim titles - CS2, Dota 2, League of Legends, Valorant, through to NBA2K and FIFA - behind per-title filters, live and past status filters, tournament dropdowns, search, and a featured-live carousel, with curated ordering, normalized names, and a consistent odds layout. The whole vertical is a feature flag on the multi-brand platform: any of the eighteen brands turns it on without a fork.

Results

Measured in the field

~29
Titles covered
1
Socket room per match
6 dp
Crypto payout math
1
Slip - singles + multiples
3
Market states handled
18
Brands can switch it on

These are properties of the build, not a campaign report: every open match holds its own socket room, every price move lands inside the betslip for the player to accept, every payout is computed in decimal arithmetic at the currency's own precision, and every market renders its real state - active, suspended, or deactivated - instead of a hopeful button. A live book's trust argument is that its numbers can be believed, so we built that in rather than claiming it.

Under the hood

The stack

  • Next.js
  • React
  • TypeScript
  • socket.io
  • Redux Toolkit
  • decimal.js
  • Turborepo
  • SCSS Modules + CSS custom properties

Building something that has to be real-time?

Sockets, live repricing, exact money math - we've shipped the parts of a betting product that can't be faked. Tell us what you're building and we'll tell you exactly how we'd approach it.

15 min · no pitch · usually within 24h