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.
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
| State | Description | Transitions |
|---|---|---|
| Connecting | Establishing WebSocket, joining room |
|
| Synced | Live with all room members |
|
| Reconnecting | Lost connection, queuing local changes |
|
| Replaying | Catching up missed events from server |
|
| Offline | User disconnected, work saved locally |
|
Easy-to-miss situations
The kinds of edge cases that break demos.
What if two users edit the same word at the same instant?
highNaive 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)?
mediumRepeated 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?
mediumServer 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?
mediumUser 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?
mediumUser 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.