home/field notes/Architecture · Web3
ArchitectureWeb3React Query

Architecting a real-time crypto exchange frontend

Order books update dozens of times a second; a naïve React tree melts. The state architecture behind keeping Pooleno & ZarinBit at 60fps under load.

KB Kambiz BaghieMar 202611 min read

The problem with "just use state"

A live order book is a firehose. WebSocket frames arrive 20–40 times a second per market, each one mutating a deep, sorted structure. Pipe that straight into React state and you re-render the entire tree on every tick — the tab heats up, scroll janks, and the numbers you most need to trust start to stutter.

The fix is to separate transient socket state from server state from UI state, and to give each one a home that matches its update frequency.

Three stores, three jobs

  • Zustand holds the live socket snapshot — the order book, last trades, ticker. It lives outside React’s render cycle and updates via setState without subscribing components that don’t read the changed slice.
  • React Query owns everything REST: markets, balances, order history. Caching, retries, and background refetch come for free.
  • Local component state stays for what it’s good at — the open/closed of a dropdown, the contents of an input.

Selectors are the whole game

The trick that keeps it at 60fps: components subscribe to the narrowest possible slice of the store, with a custom equality check so a price change in row 14 never wakes row 3.

const bestBid = useBook(
  (s) => s.bids[0]?.price,
  shallow // only re-render when THIS value changes
);
Real-time isn’t about pushing more updates to the screen. It’s about pushing the fewest updates that still read as instant.

Batch the frames, not the renders

Even with perfect selectors, 40 store writes a second is wasteful. I coalesce incoming frames into a single requestAnimationFrame flush — the socket fills a buffer, and the UI drains it once per paint. The book stays visually live while the actual React work drops by an order of magnitude.

The result across Pooleno and ZarinBit: a steady 60fps depth chart and order book, even on mid-range laptops, with the CPU mostly idle between trades.