A full-stack, real-time collaborative document editor similar to Google Docs. Multiple users can edit the same document simultaneously with operational transformation for conflict resolution.
Traditional document editing is single-user focused. When multiple people need to collaborate on a document, they face challenges with version control, conflicting changes, and lack of real-time interaction.
This application provides a real-time collaborative editing experience where:
- Multiple users can edit the same document simultaneously
- Changes are synchronized in real-time using WebSockets
- Operational Transformation algorithm resolves edit conflicts
- Users can see who else is currently editing the document
| Layer | Technology |
|---|---|
| Frontend | React, Quill.js rich text editor, Socket.IO client |
| Backend | Node.js, Express, Socket.IO, MongoDB with Mongoose |
| Real-time Communication | WebSockets via Socket.IO |
| Operational Transformation | Custom OT implementation for conflict resolution |
| Deployment | Docker, Docker Compose, Nginx |
- Operational Transformation over CRDTs: Chosen for its maturity and proven scalability in applications like Google Docs.
- Socket.IO for Real-time Communication: Provides built-in features like rooms, automatic reconnection, and fallback mechanisms.
- React with Hooks: Modern React patterns for state management and side effects.
- Containerization with Docker: Ensures consistent environments across development and production.
- MongoDB for Document Storage: Flexible schema well-suited for document content storage.
The core of the real-time collaboration is the OT algorithm that transforms concurrent operations:
function transform(opA, opB) {
let opBPrime = [];
let indexA = 0, indexB = 0;
while (indexA < opA.length && indexB < opB.length) {
const actionA = opA[indexA];
const actionB = opB[indexB];
if (isRetain(actionA)) {
if (isInsert(actionB)) {
opBPrime.push(actionB);
indexB++;
} else if (isDelete(actionB)) {
opBPrime.push(actionB);
indexB++;
} else {
indexA++;
indexB++;
opBPrime.push({ retain: actionA.retain });
}
} else if (isInsert(actionA)) {
if (isInsert(actionB)) {
opBPrime.push({ retain: actionA.insert.length });
opBPrime.push(actionB);
indexB++;
} else {
indexA++;
}
} else if (isDelete(actionA)) {
indexA++;
}
}
while (indexB < opB.length) {
opBPrime.push(opB[indexB++]);
}
return opBPrime;
}- Docker and Docker Compose
- Node.js 16+ (for local development without Docker)
-
Clone the repository:
git clone https://github.com/mosesachizz/real-time-doc-editor.git cd real-time-doc-editor -
Copy the environment example file:
cp .env.example .env
-
Update the
.envfile with your configuration if needed. -
Start the application with Docker Compose:
docker-compose up -d
-
Access the application:
- Frontend: http://localhost:3000
- Backend API: http://localhost:3001
-
Start MongoDB locally or use a cloud instance.
-
Set up the backend:
cd server npm install MONGODB_URI=mongodb://localhost:27017/collab-editor npm start -
Set up the frontend (in a new terminal):
cd client npm install REACT_APP_SERVER_URL=http://localhost:3001 npm start -
Access the application at http://localhost:3000
- Open the application in multiple browser windows or tabs
- Create a new document or select an existing one
- Start typing in different windows to see real-time collaboration
- Observe the user list to see who else is editing the document
This project is licensed under the MIT License - see the LICENSE file for details.