Skip to main content

Collaboration

AFFiNE enables seamless real-time collaboration with team members, allowing multiple users to edit documents, whiteboards, and databases simultaneously. Built on Conflict-free Replicated Data Types (CRDTs) using Y.js (Yjs), AFFiNE ensures your edits are always preserved, even when working offline.

Real-Time Editing

Collaborate with your team in real-time:
  • Live cursors: See where teammates are editing
  • Instant updates: Changes appear immediately for all users
  • Presence indicators: Know who’s viewing or editing
  • Conflict-free: Multiple users can edit the same content simultaneously
  • Undo/redo: Individual undo stacks per user
AFFiNE uses Socket.io over WebSockets for real-time communication, with automatic reconnection and offline support.

Architecture Overview

AFFiNE’s collaboration is powered by:

Y.js (Yjs) CRDT

Conflict-free Replicated Data Type ensuring all edits merge without conflicts

Socket.io Gateway

WebSocket server managing real-time connections and message broadcasting

Document Storage

PostgreSQL backend persisting document updates and snapshots

Awareness Protocol

User presence tracking cursors, selections, and online status

How It Works

CRDT-Based Sync

AFFiNE uses Y.js, a high-performance CRDT implementation:
// Simplified collaboration flow
1. User makes editY.js creates update
2. Update sent via WebSocketServer
3. Server broadcastsAll connected clients
4. Clients apply updateDocument synced
5. Updates persistedPostgreSQL
Key Benefits:
  • No locking: Users never block each other
  • Automatic merging: Concurrent edits merge intelligently
  • Offline support: Edits sync when connection returns
  • No conflicts: Mathematical guarantees of consistency

WebSocket Protocol

Real-time sync uses Socket.io events:
Client → Server:
  • space:join - Join workspace for sync
  • space:leave - Leave workspace
  • space:join-awareness - Join presence for specific doc
  • space:leave-awareness - Leave presence
Server → Client:
  • Connection acknowledgment with clientId
  • Success/failure status

Update Merging

The server optimizes network traffic:
// Multiple updates are compressed
[update1, update2, update3] → mergeUpdates() → singleUpdate

// Benefits:
- Reduced bandwidth
- Faster sync for late joiners
- Lower database writes
The SpaceSyncGateway class manages all real-time collaboration:Key Components:
  • @WebSocketGateway() - Socket.io integration
  • SpaceSyncAdapter - Protocol versioning (sync-025, sync-026)
  • WorkspaceSyncAdapter - Workspace-specific logic
  • UserspaceSyncAdapter - Personal space logic
Connection Management:
  • Tracks active users and connections
  • Implements presence user ID resolution
  • Flushes active user metrics every minute
  • Handles connection/disconnection events
Protocol Versioning:
  • Supports clients ≥ 0.25.0
  • Protocol 0.25: Single update broadcasts
  • Protocol 0.26: Batch update broadcasts (optimized)
  • Automatic protocol selection based on client version

User Presence

See who’s actively working:

Presence Indicators

  • Avatars in top-right corner show active users
  • Live cursors display teammate positions
  • Colored highlights show text selections
  • User count badge indicates total viewers

Awareness Features

In Documents

  • Cursor positions as you type
  • Block selections when highlighting
  • User name labels near cursors
  • Different colors per user

In Whiteboards

  • Mouse/pointer positions
  • Selected shapes and elements
  • Active drawing tools
  • Viewport indicators (who’s viewing where)

Permissions and Access

Workspace Roles

Control who can collaborate:
  • Owner: Full access and workspace management
  • Admin: Manage members and permissions
  • Member: Edit all workspace content
  • Guest: View-only or limited edit access
Permissions are enforced by the AccessController service before allowing WebSocket connections and document updates.

Permission Checks

// Access validation flow
1. User connectsSession authenticated
2. space:joinCheck workspace permission
3. space:push-doc-updateVerify edit rights
4. Update rejected if unauthorized

Document-Level Control

  • Blocked documents: Prevent edits with DocUpdateBlocked error
  • Read-only mode: View without edit permissions
  • Private workspaces: Invite-only access

Offline Support

Work without internet, sync when back online:

How Offline Works

  1. Local changes stored in browser IndexedDB
  2. Y.js tracks all unsent updates
  3. Connection restored → Updates sent to server
  4. Server merges offline changes with server state
  5. Conflicts resolved automatically via CRDT
You can make edits completely offline. When you reconnect, all changes will sync automatically—no data loss!

Offline Indicators

  • Red dot or warning when disconnected
  • “Syncing…” message when reconnecting
  • “Synced” checkmark when up to date

Conflict Resolution

How CRDTs Prevent Conflicts

Unlike traditional systems (last-write-wins), Y.js uses operation-based CRDTs: Example Scenario:
  • User A and User B both edit the same paragraph offline
  • User A changes “Hello” → “Hello World”
  • User B changes “Hello” → “Hi there”
  • Both reconnect at the same time
Traditional System: One edit overwrites the other (conflict!) Y.js CRDT: Both edits merge → “Hi there World” (or preserved separately)
Text Editing:
  • Character-level operations tracked
  • Position-based insertion (not index-based)
  • Tombstones for deletions (preserved for sync)
List/Array Operations:
  • Item IDs for each element
  • Concurrent insertions preserved
  • Move operations supported
Block-Level:
  • Each block has unique ID
  • Property changes merged per-field
  • Deletion tombstones
Database Rows:
  • Row-level merging
  • Cell updates merged independently
  • Last-write-wins per cell (with timestamp)

Version History

Track document changes over time:
  • Automatic snapshots created periodically
  • View history to see past versions
  • Restore to previous state
  • Compare versions side-by-side
  • Editor attribution for each change

History Storage

// Document storage architecture
Snapshot (latest stable state)
  └── Updates (incremental changes since snapshot)
      └── Squashed periodically to new snapshot
Benefits:
  • Fast document loading (from latest snapshot)
  • Complete history preservation
  • Efficient storage (updates compressed)

Performance Optimization

Server-Side

Update Compression

Multiple updates merged before broadcast to reduce bandwidth

Connection Pooling

Redis adapter for horizontal scaling across servers

Lazy Loading

Only sync document when user joins, not all workspace docs

State Vectors

Efficient diff calculation for late joiners

Client-Side

  • Debounced sends: Batch local edits before sending
  • Binary protocol: Efficient Y.js binary format
  • Incremental parsing: Apply updates without re-rendering entire doc
  • Virtual scrolling: Handle large collaborative documents

Collaborative Features by Module

Editor Collaboration

  • Paragraph-level: Multiple users edit different paragraphs
  • Inline formatting: Concurrent bold, italic, link edits
  • Block operations: Insert, delete, move blocks
  • Copy/paste: Preserve formatting and structure

Whiteboard Collaboration

  • Element positioning: Drag shapes simultaneously
  • Drawing: Concurrent pen strokes
  • Connectors: Auto-update when shapes move
  • Frames: Collaborative presentation editing

Database Collaboration

  • Row-level: Edit different rows simultaneously
  • Cell-level: Concurrent edits to different cells
  • Schema changes: Add columns collaboratively
  • View configs: Independent filters/sorts per user

Notifications

Stay informed of team activity:
  • @mentions: Get notified when mentioned
  • Page comments: Thread discussions on documents
  • Activity feed: See recent changes (coming soon)
  • Email digests: Summary of workspace activity (coming soon)

Best Practices

  1. Communicate: Use comments or chat when editing together
  2. Use sections: Divide work by headings or frames
  3. Check presence: See who’s editing before making big changes
  4. Save often: Autosave is automatic, but good to verify sync status
  5. Resolve conflicts early: Review version history if something looks wrong
  6. Use permissions: Set appropriate roles for team members

Troubleshooting

Connection Issues

Red dot or “Offline” indicator:
  • Check internet connection
  • Refresh page to reconnect
  • Check firewall/proxy settings for WebSocket support
Changes not syncing:
  • Verify you have edit permissions
  • Check sync status in bottom-right corner
  • Try disconnecting and reconnecting to workspace
Duplicate content:
  • Rare but can happen with offline conflicts
  • Check version history
  • Manually merge or restore to previous version

Performance Issues

Slow syncing:
  • Large documents may take time to load
  • Check network speed
  • Clear browser cache and reload
High memory usage:
  • Close unused workspace tabs
  • Restart browser
  • Check for browser extensions interfering

Security

Encryption

  • HTTPS/WSS: All connections encrypted in transit
  • Authentication: Session tokens required for all operations
  • Authorization: Permission checks before document access
  • Token refresh: Automatic session renewal

Data Privacy

  • Workspace isolation: Users can’t access other workspaces
  • Document-level ACLs: Fine-grained access control
  • Audit logs: Track who accessed what (enterprise)
  • GDPR compliance: Data export and deletion

Next Steps