Challenges⚡ Real-TimeDesign a Chat Application
ðŸĶ–DinosaurSystem DesignReal-TimeArchitecture

Design a Chat Application

Architect a Slack-like chat with channels, threads, real-time messages, and offline support.

Design a Chat Application

The Prompt

Design the frontend architecture for a team chat application similar to Slack with channels, direct messages, threads, and real-time updates.

Data Model

interface Message {
  id: string;
  channelId: string;
  threadId?: string;
  authorId: string;
  content: string;
  timestamp: number;
  edited?: boolean;
  reactions: Record<string, string[]>;
  attachments: Attachment[];
}
 
interface Channel {
  id: string;
  name: string;
  type: 'public' | 'private' | 'dm';
  members: string[];
  unreadCount: number;
  lastMessage?: Message;
}

Architecture Decisions

Message Loading Strategy

  • Initial load: Last 50 messages per visible channel
  • Scroll up: Fetch older messages in pages (cursor-based pagination)
  • New messages: WebSocket push → append to local store
  • Search: Server-side full-text search with highlighted results

Real-Time Connection

Single WebSocket → Multiplexed channels
  → Message events (new, edit, delete)
  → Presence events (online, typing, away)
  → Channel events (created, updated, member changes)

One WebSocket connection multiplexed across all subscribed channels. Avoids connection overhead.

State Management

                    ┌─ Channel list (sorted by last activity)
Global Store ──────┾─ Active channel messages (virtualized)
                    ├─ Thread messages (lazy loaded)
                    ├─ User presence map
                    └─ Unread counts

Offline Support

  1. IndexedDB for message cache
  2. Optimistic updates — show sent message immediately
  3. Queue — store unsent messages, retry on reconnect
  4. Conflict resolution — server timestamp is authoritative

Performance

  • Virtualize the message list — only render visible messages
  • Lazy-load images and file previews
  • Debounce typing indicators (500ms)
  • Batch unread count updates

Key Interactions

FeatureApproach
Typing indicatorDebounced broadcast, auto-expire after 3s
Message editingOptimistic update + server confirmation
ReactionsToggle mutation, optimistic UI
Thread repliesSeparate message list, lazy-loaded
@mentionsClient-side user search with fuzzy matching

The real challenge isn't sending messages — it's keeping state consistent across multiple concurrent views with minimal re-renders.