CodePark/ questions / Classic designs
START PRACTICINGPRACTICE
Frontend question · Frontend system design › Classic designs

Design the frontend of a chat / messaging app like Slack or WhatsApp Web.

Use one WebSocket for real-time events, a normalised store, a reverse virtualized message list, and optimistic sending with client ids.

Requirements:

  • a list of conversations
  • message history
  • sending text and attachments
  • real-time delivery
  • typing indicators
  • read receipts
  • unread counts

Non-functional: messages appear instantly, survive flaky networks, and long histories scroll smoothly.

Architecture:

  • A sidebar ConversationList.
  • A MessageList: a reverse virtualized list anchored at the bottom. Virtualized means only visible messages are rendered.
  • A Composer for writing messages.

A single WebSocket connection is used, because traffic is two-way and frequent. It feeds a normalised store of conversations and messages, keyed by id.

Data and API: history loads over HTTP, with cursor pagination going backwards (before=<messageId>). The socket events are message.new, message.updated, typing and read. Each one has a sequence number per conversation.

Sending:

  • Create the message locally with a client id and a pending status.
  • Render it immediately.
  • Send it over the socket.
  • When the server acknowledges it with the real id, reconcile the two.

Failed messages show a retry option. Unsent messages are saved in IndexedDB.

Optimisations:

  • Keep the scroll position anchored when older messages load at the top.
  • Auto-scroll only if the user is already at the bottom.
  • Throttle typing events, so at most one is sent per short interval.
  • Reconnect with backoff (longer waits between tries), and fetch missed messages by sequence number.

Trade-offs: a normalised store adds complexity, but it keeps data consistent across views.

  • Use a WebSocket for two-way real-time traffic.
  • Send optimistically with client ids, then reconcile when the server acknowledges.
  • Use a reverse virtualized list with scroll anchoring.
  • Use sequence numbers to fill gaps after a reconnect.
  • Normalise conversations and messages by id.