A full-stack, real-time collaborative document editing application. This platform allows multiple users to edit the same document simultaneously, mirroring the core functionality of professional collaborative tools. It leverages WebSockets for instantaneous data synchronization and provides a robust, decoupled architecture separating the client interface from the server-side logic.
- Architecture Overview
- Technology Stack
- Core Features
- Project Directory Structure
- Environment Variables
- Local Development Setup
- API Documentation
- WebSocket Event Reference
- Deployment Guide
- License
The application follows a standard client-server architecture utilizing RESTful principles for standard CRUD operations and WebSockets for real-time bidirectional communication.
- Client Layer: A lightweight, Vanilla JavaScript frontend utilizing Quill.js for rich text editing. It manages local state and communicates with the backend via REST API calls (for authentication and document retrieval) and Socket.IO (for real-time delta synchronization).
- Service Layer: An Node.js/Express backend that handles routing, authentication (Passport.js), session management, and business logic.
- Data Layer: A MongoDB database (interfaced via Mongoose) responsible for persisting user credentials, OAuth linkages, and document contents (stored as JSON-compliant Quill Deltas).
Frontend:
- HTML5 & CSS3 (Custom responsive styling, no CSS framework)
- Vanilla JavaScript (ES6+)
- Quill.js (Rich text editor framework)
- Socket.IO Client (Real-time connection handling)
Backend:
- Node.js & Express.js (Runtime and web framework)
- Socket.IO (WebSocket protocol abstraction)
- MongoDB & Mongoose (NoSQL Database and ODM)
- Passport.js (Authentication middleware supporting Local and Google OAuth2 strategies)
- Express-Session (Session management)
- Real-Time Collaboration: Multiple users can edit a document concurrently. Changes are synchronized across all connected clients with minimal latency using Operational Transformation (handled via Quill Deltas).
- Authentication System: Secure user registration and login flows. Supports traditional email/password credentials alongside seamless Google OAuth2 integration.
- Document Management: Users possess a personalized dashboard to view, create, and access their documents.
- Auto-Saving: Document states are automatically broadcasted and persisted to the database during active editing sessions.
- Cross-Origin Configuration: Fully configured to support decoupled deployments (e.g., frontend hosted on Vercel communicating with a backend hosted on Render) requiring strict CORS policies and cross-site cookie transmission.
├── backend/
│ ├── config/
│ │ └── passport.js # Passport strategies (Local and Google OAuth)
│ ├── models/
│ │ ├── Document.js # Mongoose schema for document persistence
│ │ └── User.js # Mongoose schema for user accounts
│ ├── routes/
│ │ ├── authRoutes.js # Endpoints for login, register, and OAuth callbacks
│ │ └── docRoutes.js # Endpoints for document creation and retrieval
│ ├── .env # Environment configuration (ignored in version control)
│ └── server.js # Main application entry point and socket handler
├── frontend/
│ ├── css/
│ │ └── styles.css # Global stylesheet and UI components
│ ├── js/
│ │ ├── auth.js # Handles client-side authentication requests
│ │ ├── config.js # Global configuration (e.g., target BACKEND_URL)
│ │ ├── dashboard.js # Manages the document list interface
│ │ └── editor.js # Initializes Quill.js and handles socket events
│ ├── dashboard.html # Protected view for listing documents
│ ├── editor.html # Protected view for editing a specific document
│ └── index.html # Public landing, login, and registration view
├── .gitignore # Excluded files and directories
├── package.json # Project dependencies and npm scripts
└── vercel.json # Configuration for Vercel deployment
The backend requires specific environment variables to function correctly. Create a .env file in the backend/ directory with the following keys:
# Application Port (Defaults to 5000 if omitted)
PORT=5000
# MongoDB Connection String (Atlas or Local)
MONGODB_URI=mongodb+srv://<username>:<password>@cluster0.mongodb.net/<dbname>?retryWrites=true&w=majority
# Session Encryption Key (Use a strong, randomized string)
SESSION_SECRET=your_secure_session_secret
# Google OAuth2 Credentials
GOOGLE_CLIENT_ID=your_google_client_id_here
GOOGLE_CLIENT_SECRET=your_google_client_secret_here- Clone the repository to your local machine.
- Navigate to the root directory and run
npm installto install all required Node.js packages. - Configure your
backend/.envfile as detailed in the Environment Variables section. - Execute
npm startto spin up the Express and Socket.IO server. You should see "Server running on port 5000" and "MongoDB connected" in your terminal.
- Navigate to
frontend/js/config.js. - Ensure
BACKEND_URLis set to your local server address (e.g.,const BACKEND_URL = 'http://localhost:5000';). - Open
frontend/index.htmldirectly in your browser or serve thefrontend/directory using an extension like VSCode Live Server.
POST /register: Acceptsname,email, andpassword. Creates a new local user.POST /login: Acceptsemailandpassword. Authenticates the user and sets an HTTP-only session cookie.GET /current-user: Returns the currently authenticated user's profile based on the session cookie.POST /logout: Destroys the current session.GET /google: Initiates the Google OAuth2 flow.GET /google/callback: The redirect endpoint for Google OAuth2.
GET /: Retrieves all documents owned by the authenticated user, sorted by the most recently updated.POST /: Initializes and saves a new, empty document to the database.GET /:id: Retrieves the metadata and contents of a specific document by its MongoDB ObjectId.
The Socket.IO server listens for and emits specific events to handle real-time collaboration.
get-document: Sent when a client opens a document. Payload:documentId. Triggers the server to join the client to a specific room.send-changes: Sent when a client types or formats text. Payload: Quill Delta object.save-document: Sent periodically by the client to persist the current document state to MongoDB. Payload: Full Quill Delta contents.
load-document: Emitted by the server upon successfully joining a room. Payload: The current document contents retrieved from the database.receive-changes: Emitted by the server to broadcast changes made by one client to all other clients currently residing in the same document room.
This application is designed to be deployed across two separate services to maximize scalability.
- Push the repository to GitHub.
- Create a new "Web Service" in Render and connect your repository.
- Set the Build Command to
npm install. - Set the Start Command to
npm start. - Under the Environment tab, input all variables listed in the Environment Variables section.
- Deploy the service and note the generated Render URL.
- Update
frontend/js/config.jsand changeBACKEND_URLto the live Render URL you just generated. - Ensure the Google OAuth Authorized Redirect URIs in your Google Cloud Console are updated to point to the live Vercel and Render URLs.
- Commit and push these changes to GitHub.
- Import the repository into Vercel.
- In the Vercel project settings, explicitly set the "Root Directory" to
frontend. - Deploy the application.
This project is licensed under the ISC License.