A production-ready, real-time collaborative document editor enabling multiple users to edit, sync and manage documents simultaneously — powered by Socket.IO, Firebase and a modern React frontend.
| Property | Details |
|---|---|
| 🏷️ Project Name | Real-Time Collaborative Document Editor |
| 🆔 Task ID | WD-3 |
| 🌐 Domain | Full-Stack Web Development |
| ⚡ Difficulty | Intermediate |
| 📅 Assigned Date | 21st May 2026 |
| ⏳ Submission Deadline | 30th May 2026 |
| 🏢 Organization | TEYZIX CORE |
| 👨💻 Developer | Muhammad Yasir |
A full-stack real-time collaborative document editor built with React, Node.js, Express, Socket.io and Firebase. It allows multiple users to edit documents simultaneously with live synchronization, secure authentication, role-based access and real-time user presence tracking for a smooth collaborative experience.
Built with scalability and modern productivity in mind, the platform delivers a clean SaaS-style workspace with fast performance and seamless team collaboration.
- 📄 Building a Real-Time Collaborative Editor
- ⚡ Building a Modern Real-Time Collaborative Document Editor
This project showcases a modern collaborative workspace designed for remote teams and productivity-focused environments. It combines real-time communication, concurrent editing, and responsive UI/UX to create a smooth and interactive editing experience.
The system demonstrates practical implementation of WebSockets, authentication workflows, and scalable backend architecture inspired by modern collaboration platforms.
Existing third-party collaboration tools often create limitations in:
- 🔒 Data ownership & privacy control
- ⚙️ Customization flexibility
- 📈 Scalability and integration options
- 💸 Cost at scale
This project builds a self-hosted alternative with full control over architecture, data, and features.
| Feature | Description |
|---|---|
| ⚡ Live Sync | Changes broadcast instantly to all connected users via Socket.IO |
| 👥 Presence Tracking | See who is online, typing, and editing in real time |
| 🖱️ Cursor Tracking | Live cursor and selection indicators per collaborator |
| 🔄 Reconnection Handling | Auto-reconnect logic with state recovery on disconnect |
| 💾 Auto-Save | Debounced auto-save with visual status indicators |
| 🔀 Conflict Strategy | Last-write-wins with room-based document locking |
| Feature | Description |
|---|---|
| ➕ Create | Instantly create new documents with generated IDs |
| ✏️ Rename | Real-time document renaming across all sessions |
| 🗑️ Delete | Owner-only document deletion with confirmation |
| 🔍 Search | Client-side document search with live filtering |
| 📜 Version History | Timeline UI with restore placeholders (Firestore-ready) |
| 📋 Dashboard | SaaS-style document dashboard with responsive sidebar |
| Feature | Description |
|---|---|
| 📧 Email/Password | Firebase Auth with registration and login flows |
| 🔵 Google SSO | One-click Google Sign-In integration |
| 🛡️ Protected Routes | React Router guards for authenticated-only pages |
| 🎭 Role-Based Access | Owner / Editor / Viewer permission system |
| 🔑 Dev Mode | Auth bypass for local development without Firebase |
| Role | 👁️ Read | ✍️ Write | 🗑️ Delete | 🏷️ Rename | 👥 Invite |
|---|---|---|---|---|---|
| 👑 Owner | ✅ | ✅ | ✅ | ✅ | ✅ |
| ✏️ Editor | ✅ | ✅ | ❌ | ❌ | ❌ |
| 👁️ Viewer | ✅ | ❌ | ❌ | ❌ | ❌ |
┌─────────────────────────────────────────────────────────────┐
│ CLIENT (React + Vite) │
│ React Router │ Context API │ TipTap Editor │ Tailwind CSS │
└──────────────────────┬──────────────────┬────────────────────┘
│ REST API │ Socket.IO (WS)
┌────────────▼──────────────────▼──────────────┐
│ SERVER (Node.js + Express) │
│ Controllers │ Services │ Middleware │ Sockets │
└──────────────────────┬────────────────────────┘
│ Firebase Admin SDK
┌──────────────────────▼────────────────────────┐
│ Firebase Platform │
│ Firestore Database │ Firebase Authentication │
└───────────────────────────────────────────────┘
rt-collaborative-doc-editor-fs3/
│
├── 📦 client/ # React + Vite Frontend
│ └── src/
│ ├── 🧩 components/
│ │ ├── auth/ # Login, Register, GoogleSSO
│ │ ├── dashboard/ # DocumentCard, Sidebar, SearchBar
│ │ ├── editor/ # TipTap, CollaboratorPanel, StatusBar
│ │ ├── layout/ # AppLayout, Navbar, ThemeToggle
│ │ └── common/ # Button, Modal, LoadingSpinner
│ │
│ ├── 📄 pages/
│ │ ├── Login.jsx
│ │ ├── Register.jsx
│ │ ├── Dashboard.jsx
│ │ └── Editor.jsx
│ │
│ ├── 🔌 context/
│ │ ├── AuthContext.jsx # Firebase auth state
│ │ ├── ThemeContext.jsx # Dark / Light mode
│ │ └── SocketContext.jsx # Socket.IO provider
│ │
│ ├── 🪝 hooks/
│ │ ├── useDocuments.js # CRUD + state management
│ │ ├── useEditor.js # TipTap + sync logic
│ │ └── useDebounce.js # Auto-save debouncing
│ │
│ ├── 🔧 services/
│ │ ├── api.js # Axios REST layer
│ │ ├── auth.service.js # Firebase Auth wrapper
│ │ └── socket.service.js # Socket.IO client setup
│ │
│ └── ⚙️ config/
│ ├── env.js # Environment variable helpers
│ └── firebase.js # Firebase client config
│
├── 🖥️ server/ # Node.js + Express Backend
│ └── src/
│ ├── 🎮 controllers/
│ │ ├── auth.controller.js
│ │ └── document.controller.js
│ │
│ ├── 🔧 services/
│ │ ├── document.service.js # Business logic + in-memory store
│ │ └── firestore.placeholder.js # Firestore integration stubs
│ │
│ ├── ⚡ sockets/
│ │ └── document.socket.js # Real-time event handlers
│ │
│ ├── 🛡️ middleware/
│ │ ├── auth.middleware.js # Token verification
│ │ ├── validation.middleware.js
│ │ └── error.middleware.js
│ │
│ └── 📐 models/
│ └── document.model.js # Firestore-ready schema
│
└── 📚 docs/
├── architecture/overview.md
└── api-docs/
├── rest-api.md
└── socket-events.md
├─ .gitignore
├─ FIREBASE_SETUP.md
├─ package-lock.json
├─ package.json
├─ PROJECT_COMPLETION.md
├─ QUICKSTART.md
└─ README.md
| Event | Payload | Description |
|---|---|---|
join-document |
{ docId, userId, role } |
Join a document editing room |
document-update |
{ docId, content, version } |
Broadcast content change |
cursor-update |
{ docId, userId, position } |
Share cursor position |
leave-document |
{ docId, userId } |
Leave a document room |
| Event | Payload | Description |
|---|---|---|
document-updated |
{ content, userId, version } |
Receive remote content change |
presence-update |
{ users: [...] } |
Collaborators list changed |
cursor-broadcast |
{ userId, position, color } |
Receive a remote cursor |
user-joined |
{ user } |
New collaborator joined |
user-left |
{ userId } |
Collaborator disconnected |
node --version # v18.0.0 or higher required
npm --version # v9.0.0 or higher requiredgit clone https://github.com/YasirAwan4831/rt-collaborative-doc-editor-fs3.git
cd rt-collaborative-doc-editor-fs3npm run install:all# Server Configuration
PORT=5000
CLIENT_URL=http://localhost:5173
# Development Mode (no Firebase required)
AUTH_DEV_MODE=true
# Firebase Admin (required when AUTH_DEV_MODE=false)
FIREBASE_PROJECT_ID=your-project-id
FIREBASE_CLIENT_EMAIL=your-service-account@project.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"# API Configuration
VITE_API_URL=http://localhost:5000/api/v1
VITE_SOCKET_URL=http://localhost:5000
# Development Mode (sign in with any email)
VITE_AUTH_DEV_MODE=true
# Firebase Client Config (required when VITE_AUTH_DEV_MODE=false)
VITE_FIREBASE_API_KEY=your-api-key
VITE_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your-project-id
VITE_FIREBASE_STORAGE_BUCKET=your-project.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=your-sender-id
VITE_FIREBASE_APP_ID=your-app-idnpm run dev| Service | URL | Description |
|---|---|---|
| 🖥️ Frontend | http://localhost:5173 |
React + Vite client |
| 🔧 API Server | http://localhost:5000/api/v1 |
REST endpoints |
| 💓 Health Check | http://localhost:5000/api/v1/health |
Server status |
- Visit Firebase Console
- Click Add project → follow setup wizard
- Enable Authentication → Sign-in methods → Email/Password + Google
# Firebase Console → Project Settings → Your Apps → Add Web App
# Copy the config object to client/.env as VITE_FIREBASE_* variables# Firebase Console → Project Settings → Service Accounts
# Generate new private key → download JSON
# Extract values to server/.env# server/.env
AUTH_DEV_MODE=false
# client/.env
VITE_AUTH_DEV_MODE=falsefirestore/
├── users/{uid}
│ ├── email: string
│ ├── displayName: string
│ └── createdAt: timestamp
│
├── documents/{docId}
│ ├── title: string
│ ├── content: string (TipTap JSON)
│ ├── ownerId: string
│ ├── collaborators: map
│ ├── createdAt: timestamp
│ └── updatedAt: timestamp
│
└── documents/{docId}/versions/{versionId}
├── content: string
├── savedBy: string
└── savedAt: timestamp
# In server/src/services/document.service.js
# Replace in-memory store logic with Firestore calls
# Reference: server/src/services/firestore.placeholder.js| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/auth/verify |
❌ | Verify Firebase ID token |
GET |
/documents |
✅ | List user's documents |
POST |
/documents |
✅ | Create new document |
GET |
/documents/:id |
✅ | Get document by ID |
PATCH |
/documents/:id |
✅ | Update document content |
PATCH |
/documents/:id/rename |
✅ | Rename document (owner only) |
DELETE |
/documents/:id |
✅ | Delete document (owner only) |
GET |
/documents/:id/versions |
✅ | Get version history |
📖 Full API documentation:
docs/api-docs/rest-api.md
| Command | Description |
|---|---|
npm run install:all |
Install root, client, and server dependencies |
npm run dev |
Run client + server concurrently |
npm run dev:client |
Frontend only (localhost:5173) |
npm run dev:server |
Backend only (localhost:5000) |
npm run build |
Build client for production |
npm start |
Start production server |
# Build production bundle
cd client && npm run build
# Vercel
vercel --prod
# Netlify
netlify deploy --prod --dir=distRequired environment variables in hosting dashboard:
VITE_API_URL=https://your-api.railway.app/api/v1
VITE_SOCKET_URL=https://your-api.railway.app
VITE_AUTH_DEV_MODE=false
VITE_FIREBASE_* (all Firebase client config values)
# Start production server
cd server && npm startRequired environment variables:
NODE_ENV=production
PORT=5000
CLIENT_URL=https://your-frontend.vercel.app
AUTH_DEV_MODE=false
FIREBASE_PROJECT_ID=...
FIREBASE_CLIENT_EMAIL=...
FIREBASE_PRIVATE_KEY=...
⚠️ Monorepo Tip: Deployclient/andserver/separately. EnsureCLIENT_URLin server matches the deployed frontend domain exactly for CORS to work.
- 🖊️ Operational Transformation (OT) — True conflict-free concurrent editing
- 🗺️ Live Cursor Rendering — Visual cursor positions per user in TipTap
- 🔔 Notifications System — In-app alerts for document shares and mentions
- 📱 Mobile Optimization — Touch-friendly editing experience
- 🌍 Internationalization (i18n) — Multi-language support
- 📊 Analytics Dashboard — Document activity and collaboration stats
- 🤖 AI Writing Assistant — Integrated AI suggestions via Gemini / OpenAI
- 📤 Export Options — PDF, DOCX, Markdown export
- 🔗 Public Share Links — View-only shareable document URLs
- 📂 Folder Organization — Workspace folders and document nesting
| Issue | Cause | Fix |
|---|---|---|
CORS error on API calls |
CLIENT_URL mismatch |
Ensure CLIENT_URL in server/.env matches frontend origin exactly |
| Socket not connecting | Wrong socket URL | Verify VITE_SOCKET_URL in client/.env points to backend |
Firebase auth/invalid-api-key |
Wrong client config | Double-check all VITE_FIREBASE_* values in client/.env |
Cannot read user on login |
AUTH_DEV_MODE mismatch |
Both client and server must have the same AUTH_DEV_MODE value |
| Port 5000 already in use | Another process running | Run lsof -ti:5000 | xargs kill then restart |
| Blank editor on load | Missing document ID | Check the URL contains a valid :docId param |
| Prefix | Description |
|---|---|
feat: |
New feature |
fix: |
Bug fix |
docs: |
Documentation update |
style: |
Formatting, no code logic change |
refactor: |
Code restructure without feature change |
chore: |
Build process or tooling updates |
💡 Screenshots will be added after UI finalization
| View | Preview |
|---|---|
| 🔐 Login Page | docs/screenshots/login.png |
| 📊 Dashboard | docs/screenshots/dashboard.png |
| ✍️ Editor (Multi-user) | docs/screenshots/editor.png |
| 🌙 Dark Mode | docs/screenshots/dark-mode.png |
Custom Property License — Internship / Portfolio Project (WD-3)
© 2026 Muhammad Yasir — TEYZIX CORE
This project is built as an internship deliverable and portfolio showcase. Not for commercial redistribution without explicit permission.