โ† Pattern library

Collaboration

Real-time Collaboration

Multiple users see each other's presence and changes to a shared resource in real-time (cursor positions, edits, selections), like Figma or Google Docs.

๐ŸŒณ

When to use this

For collaborative editing, multi-player whiteboards, live dashboards, or any scenario where stale views break trust.

collabrealtimewebsocketpresencesyncmultiplayer
โœจ Built using these library patterns:
realtime-share

What I assumed

I made these guesses to fill gaps. Let me know if any are wrong.

    Flow diagram

    Step-by-step recipe

    Copy this and paste into Cursor, Claude Code, or v0.

    PATTERN: Real-time Collaboration
    INPUT: room_id (resource), user, action_event
    OUTPUT: synced_state_across_users
    
    SETUP_STEPS:
      1. User opens shared resource โ†’ join "room" via WebSocket / Pusher / Liveblocks
      2. Server adds user to room presence list
      3. Broadcast "User X joined" to other room members
      4. Server sends current resource state to new user
    
    SYNC_STEPS (per action):
      1. User performs action (edit, cursor move, selection)
      2. Apply optimistically to local state (instant UI feedback)
      3. Send action event to server with vector clock or operation ID
      4. Server validates (permission, conflict resolution)
      5. Server broadcasts to all OTHER room members (not back to origin)
      6. Other members receive event, apply to their local state
      7. Show subtle visual feedback (e.g., "Alice typing..." or remote cursor)
    
    PRESENCE_STEPS (continuous):
      1. Each client sends heartbeat every 5s
      2. Server tracks last-seen per user
      3. If no heartbeat in 15s โ†’ mark user as "disconnected"
      4. Broadcast presence updates so others see who's actually live
    
    ERROR_HANDLING:
      - Conflict (two users edit same field) โ†’ use CRDT or operational transform; OR last-write-wins with toast
      - Network drops โ†’ queue actions locally, replay on reconnect
      - User goes offline โ†’ mark as disconnected, save their work for next session
      - Stale state on reconnect โ†’ server sends snapshot + replay of missed events
    
    EXTENSION_POINTS:
      - Comments anchored to selection (composable_with: ["comment"])
      - Mentions trigger toasts (composable_with: ["mention"])
      - All actions logged to activity feed (composable_with: ["activity-feed"])
      - Permissions per user (read-only, edit, admin)
    

    States โ€” how things change

    StateDescriptionTransitions
    ConnectingEstablishing WebSocket, joining room
    • Joinedโ†’Synced
    SyncedLive with all room members
    • Action receivedโ†’Synced
    • Connection lostโ†’Reconnecting
    ReconnectingLost connection, queuing local changes
    • Reconnectedโ†’Replaying
    • Timeoutโ†’Offline
    ReplayingCatching up missed events from server
    • Caught upโ†’Synced
    OfflineUser disconnected, work saved locally
    • User reopensโ†’Connecting

    Easy-to-miss situations

    The kinds of edge cases that break demos.

    • What if two users edit the same word at the same instant?

      high

      Naive last-write-wins discards one edit silently.

      Suggested handling: Use a CRDT library (Yjs, Automerge) for collaborative text. Don't roll your own โ€” collaborative editing is one of the hardest CS problems. Yjs handles 99% of cases.

    • What if a user's WiFi flickers (3 disconnects in a minute)?

      medium

      Repeated full state syncs eat bandwidth; constant "joined/left" toasts annoying.

      Suggested handling: Debounce reconnect (wait 2s before broadcasting "left"). Send delta from last known state, not full snapshot. Suppress repeated join/leave for same user within 30s.

    • What if 50 users try to edit the same document at once?

      medium

      Server can't broadcast 50 cursor updates per frame, performance degrades.

      Suggested handling: Throttle high-frequency events (cursor moves: 30fps max, broadcast at 10fps). Hard cap users per room (e.g., 25). For larger groups, switch to "view-only with comments" mode.

    • What if a user is viewing a stale version while others edit?

      medium

      User makes decision based on outdated info.

      Suggested handling: Show subtle indicator "Last update: 5s ago" or "X others editing now". Auto-fetch latest when window regains focus. Banner if stale > 30s.

    • What if WebSocket is blocked by corporate firewall?

      medium

      User can't collaborate, no clear error.

      Suggested handling: Fall back to long-polling or Server-Sent Events. Detect connection failure, show "Real-time disabled โ€” refresh to see updates" with manual refresh button.

    Composes well with

    Combine these patterns when you need a richer flow.

    Build a flow starting from this pattern โ†’