| Metric | Value |
|---|---|
| Total SLOC | 8,282 |
| Source Files | 44 |
| .ts | 4,731 |
| .md | 2,648 |
| .tsx | 553 |
| .json | 135 |
| .yml | 103 |
A collaborative document editing system enabling multiple users to edit documents simultaneously with real-time synchronization, conflict resolution, and presence indicators. This educational project focuses on building a Google Docs-like experience with Operational Transformation (OT) based synchronization.
- Multiple concurrent editors
- Live cursor positions
- Real-time text updates
- Presence indicators
- Operational Transformation (OT) algorithm
- Server-authoritative ordering
- Intent preservation
- Automatic conflict resolution
- Create and list documents
- Document persistence
- Version tracking
- Snapshots for efficient loading
- Clean, minimal interface
- Connection status indicators
- Sync status display
- User color coding
- Frontend: TypeScript + Vite + React 19 + Zustand + Tailwind CSS
- Backend: Node.js + Express + WebSocket (ws)
- Database: PostgreSQL (documents, operations, snapshots)
- Cache: Redis (presence, real-time state)
- Node.js 18+
- Docker and Docker Compose (for databases)
- npm or pnpm
# From the collaborative-editor directory
docker-compose up -dThis starts:
- PostgreSQL on port 5432
- Redis on port 6379
cd backend
npm install
npm run devThe backend runs on http://localhost:3001
cd frontend
npm install
npm run devThe frontend runs on http://localhost:5173
- Open http://localhost:5173 in multiple browser tabs
- Select different users in each tab
- Open the same document
- Start typing to see real-time collaboration
If you prefer to run PostgreSQL and Redis natively:
# Install PostgreSQL (macOS)
brew install postgresql@16
brew services start postgresql@16
# Create database and user
createuser -s collab
createdb collaborative_editor -O collab
# Run the init script
psql -U collab -d collaborative_editor -f backend/init.sql# Install Redis (macOS)
brew install redis
brew services start redisCreate backend/.env:
PORT=3001
DB_USER=collab
DB_PASSWORD=collab123
DB_HOST=localhost
DB_PORT=5432
DB_NAME=collaborative_editor
REDIS_URL=redis://localhost:6379
CORS_ORIGIN=http://localhost:5173collaborative-editor/
├── architecture.md # System design documentation
├── claude.md # Development notes
├── docker-compose.yml # Infrastructure setup
├── backend/
│ ├── package.json
│ ├── tsconfig.json
│ ├── init.sql # Database schema
│ └── src/
│ ├── index.ts # Entry point
│ ├── routes/
│ │ └── api.ts # REST endpoints
│ ├── services/
│ │ ├── TextOperation.ts # OT operation class
│ │ ├── OTTransformer.ts # Transform & compose
│ │ ├── DocumentState.ts # Document state manager
│ │ ├── SyncServer.ts # WebSocket server
│ │ ├── database.ts # PostgreSQL client
│ │ └── redis.ts # Redis client
│ └── types/
│ └── index.ts # TypeScript types
└── frontend/
├── package.json
├── vite.config.ts
├── tailwind.config.js
└── src/
├── main.tsx # Entry point
├── App.tsx # Main app component
├── index.css # Global styles
├── components/
│ ├── TextEditor.tsx # Main editor
│ ├── UserList.tsx # Collaborator list
│ ├── Header.tsx # Top bar
│ ├── DocumentList.tsx # Document picker
│ └── UserSelector.tsx # User switcher
├── services/
│ ├── TextOperation.ts # Client OT
│ ├── OTTransformer.ts # Client transform
│ └── api.ts # REST client
├── stores/
│ └── editorStore.ts # Zustand state
└── types/
└── index.ts # TypeScript types
OT is an algorithm for handling concurrent document edits. When two users make edits at the same time:
- Each client applies their change locally for instant feedback
- Changes are sent to the server with a version number
- The server transforms incoming operations against any concurrent ops
- Transformed operations are broadcast to all clients
- Clients transform remote operations against their pending local ops
- All clients converge to the same document state
- Retain(n): Skip n characters (used for positioning)
- Insert(str): Insert string at current position
- Delete(n): Delete n characters at current position
If Alice types "Hello" at position 0, and Bob types "World" at position 0 simultaneously:
- Alice's operation:
Insert("Hello") - Bob's operation:
Insert("World") - Server receives Alice's first, applies it
- Server transforms Bob's against Alice's:
Retain(5), Insert("World") - Result: "HelloWorld" (deterministic ordering)
GET /api/documents- List all documentsGET /api/documents/:id- Get document metadataPOST /api/documents- Create new documentPATCH /api/documents/:id- Update document titleGET /api/users- List all usersGET /api/users/:id- Get user info
Connect to: ws://localhost:3001/ws?documentId=<id>&userId=<id>
Messages:
init- Initial document state and client listoperation- Send/receive operationsack- Server acknowledged operationcursor- Cursor position updatesclient_join/client_leave- Presence updatesresync- Full resync on error
- Open the app in two browser windows side by side
- Select different users (Alice, Bob, Charlie)
- Open the same document in both windows
- Type in one window and watch changes appear in the other
- Try typing simultaneously to see conflict resolution
- Core OT algorithm (insert, delete, retain)
- Transform and compose functions
- WebSocket sync server
- Client sync engine with pending operations
- PostgreSQL persistence (operations, snapshots)
- Redis presence tracking
- Text editor with real-time updates
- User presence indicators
- Cursor position tracking
- Document creation and listing
- Rich text formatting
- Comments and suggestions
- Version history UI
- Offline support
- Consistency: OT ensures all clients converge to identical state
- Latency: Optimistic local updates with server reconciliation
- Conflicts: Transform function handles concurrent edits
- Scale: Designed to support 50+ simultaneous editors
- Durability: Operations logged for complete history
See architecture.md for detailed system design documentation.
See claude.md for development insights and design decisions.
- Operational Transformation (Wikipedia) - Overview of OT algorithms and history
- Google Wave OT Paper - Jupiter collaboration system and OT
- Understanding CRDTs - Conflict-free Replicated Data Types explained
- Yjs CRDT Documentation - Popular CRDT implementation for collaborative editing
- How Figma's Multiplayer Technology Works - CRDT-based real-time collaboration
- Building a Collaborative Text Editor - Deep dive into OT vs CRDT trade-offs
- Real-Time Collaboration in Google Docs - Google's approach to document structure
- Automerge: A CRDT Library - JSON-like CRDT for collaborative applications
- OT.js: Operational Transformation Library - Reference implementation of OT
- Quill Delta Format - Rich text representation for collaborative editing