CodeRoom is a MERN + Socket.io collaborative code editor for the Kodex Mini Hack-Sprint. Users authenticate, create or join a room, and edit one shared document in near real time with MongoDB persistence.
.
|-- api/ # Express, MongoDB, Redis, Socket.io backend
|-- web/ # React Vite frontend
|-- package.json
|-- .gitignore
`-- TEAM_GUIDE.md- Frontend: React, Vite, Tailwind CSS, React Router, Redux Toolkit, Axios, Monaco Editor, Socket.io client
- Backend: Node.js, Express, MongoDB/Mongoose, Redis, Socket.io
- Auth: Google auth with HTTP-only auth cookies
- Architecture: class-based route, controller, service, repository, model, validator, DTO, and interface layers
Domain A - Auth and Room Management: Nihal
Domain B - Document and Sync Engine: Sujal
Domain C - Realtime and Presence: Nayan
MongoDB Persistence: Sujal
Live deployed link: https://coderoomcollab.vercel.app- Google sign-in redirects authenticated users to the dashboard.
- Dashboard supports create room, join room by code/password, invite-link join, room history, host close-room control, and profile editing.
- Room creation generates a six-character shareable room code and stores a hashed room password.
- The editor loads the saved document snapshot and sends position-based patches through Socket.io.
- Document content, version, last editor, and patch history persist in MongoDB.
- Document HTTP and socket sync are guarded by room membership.
The client does not send the full document on every edit. Monaco changes are converted into a compact patch: baseVersion, position, deleteCount, and insertText. The server is authoritative and stores a monotonically increasing document version plus recent patch history. If a client sends a stale patch, the server shifts its position across accepted patches after that client's baseVersion, applies the transformed patch, and returns a visible conflict reason. This keeps concurrent inserts from overwriting each other without using banned CRDT/OT libraries like Yjs, ShareDB, or Automerge.
api/src
|-- app.js
|-- server.js
|-- config/
|-- modules/
| |-- auth/
| |-- rooms/
| |-- documents/
| `-- presence/
|-- shared/
| |-- constants/
| |-- errors/
| |-- middleware/
| |-- utils/
| `-- validators/
`-- sockets/Each module follows this shape:
module/
|-- module.route.js
|-- module.controller.js
|-- module.service.js
|-- module.repository.js
|-- module.model.js
|-- module.validator.js
|-- module.dto.js
`-- module.interface.jsGET /api/v1/auth/mePATCH /api/v1/auth/mePOST /api/v1/rooms/createPOST /api/v1/rooms/joinPOST /api/v1/rooms/join-linkGET /api/v1/rooms/historyPATCH /api/v1/rooms/:roomCode/closeGET /api/v1/documents/:roomCodePATCH /api/v1/documents/:roomCode/patch
document:joindocument:snapshotdocument:patchdocument:patch:applieddocument:sync:errorpresence:typing:startpresence:typing:stopdocument:typing
Install dependencies:
npm run install:allCreate environment files:
cp api/.env.example api/.env
cp web/.env.example web/.envRun both apps from the root:
npm run devRun individually:
npm run dev:api
npm run dev:webnpm run dev- run API and web togethernpm run dev:api- run only backendnpm run dev:web- run only frontendnpm run build- build frontendnpm run start- start backendnpm run lint- lint frontend
npm --prefix web run build
Get-ChildItem -Recurse -File api/src -Filter *.js | ForEach-Object { node --check $_.FullName }
git diff --check- Do not use CRDT/OT libraries like Yjs, ShareDB, or Automerge.
- Do not send full-document payloads for per-keystroke sync.
- Do not add code execution.
- Deploy frontend, backend, sockets, and MongoDB persistence before submission.
- Keep commit messages clear and tied to domain ownership.