How yashh0225/codecollab works
1. What this repo is
- CodeCollab is a split-system collaborative code editor: a browser client, a REST API, and a dedicated real-time sync server.
- The core architectural idea is that code editing state is not managed by the REST server; it is managed by Yjs CRDT documents relayed over WebSockets.
2. Client boundary: React + Vite editor app
- client/src is the browser application built with React/Vite.
- App.jsx and pages/ provide routing for the landing page, room page, and OAuth callback.
- The main user-facing editing surface is components/Editor.jsx, backed by Monaco Editor and Yjs bindings.
3. Editor subsystem
- Editor.jsx, Toolbar.jsx, Sidebar.jsx, StatusBar.jsx, and HistoryPanel.jsx form the in-room UI.
- The editor binds Monaco to Yjs; the toolbar handles room/language actions; the sidebar shows room and collaborators; the status bar shows cursor and connection info.
- History is surfaced as saved snapshots, but restoring a snapshot still pushes a normal collaborative document change through Yjs.
4. Client state/sync hooks
- hooks/useYjs.js initializes the Yjs document and connects the browser to the WebSocket sync layer.
- hooks/useAwareness.js handles ephemeral presence data such as usernames, cursor positions, and colors.
- These hooks are the boundary between the React UI and the real-time collaboration protocol.
5. REST API boundary: Express server
- server/index.js is the HTTP API entry point.
- routes/auth.js handles registration, login, JWT issuance, and OAuth flows for Google/GitHub.
- routes/rooms.js handles room creation, room lookup, and snapshot history.
- middleware/auth.js gates protected endpoints using JWT verification.
6. Persistence and relational data
- PostgreSQL is the durable store for users, rooms, and snapshots, as described in the schema in the README.
- The database is accessed from server/db.js; the README also describes a demo/in-memory fallback when Supabase credentials are absent.
- This means user identity and historical room metadata live separately from live document sync state.
7. Real-time sync boundary: dedicated Yjs websocket server
- sync-server/server.js is a separate Node process using y-websocket.
- Its role is intentionally narrow: accept Yjs binary updates, broadcast them to room peers, and maintain room membership.
- It does not interpret code syntax or application semantics; it only moves CRDT updates.
8. Document persistence for live collaboration
- sync-server/persistence.js stores and reloads Yjs document state in Redis.
- The README describes Redis as the fast persistence/cache layer for serialized Y.Doc state, so new clients can hydrate a room quickly without replaying full edit history.
- This is the persistence layer for live editor content, distinct from PostgreSQL snapshots.
9. Awareness/presence is separate from document data
- Cursor position, user names, and collaborator colors are carried through Yjs awareness, not the document itself.
- These values are ephemeral: they drive live UI like colored cursors and online user lists, but they are not meant to be persisted across disconnects.
10. Primary data flows
- Auth flow: browser → Express /auth/* → PostgreSQL/Supabase → JWT returned to client.
- Room flow: browser → Express /rooms → PostgreSQL room record → client navigates to room page.
- Edit flow: Monaco input → Yjs document in browser → WebSocket sync server → other clients’ Yjs docs → Monaco re-renders.
- Presence flow: browser awareness state → sync server relay → sidebar/cursor UI updates.
- History flow: client requests/creates snapshot via Express → PostgreSQL snapshot row; restoring a snapshot updates the Yjs document and propagates like any other edit.
11. Deployment/runtime separation
- The architecture is explicitly three runnable services: client on Vercel, REST API on Render, and WebSocket sync on Railway.
- External managed services are used for state: Supabase PostgreSQL and Upstash Redis.
- This separation matters: HTTP auth/CRUD, live collaboration, and persistence each scale and fail independently.
12. What to draw in an architecture diagram
- Show the browser client as one box with Monaco/Yjs/UI components inside.
- Show the Express API as a separate box connected to PostgreSQL.
- Show the Yjs WebSocket server as a separate box connected to Redis and to all browsers.
- Treat presence as an overlay on the WebSocket path, and treat snapshots as a relational side channel through the REST API.
Main entry points: Editor.jsx Editor · rooms.js Room routes · pages Pages · index.js Express server
Components 19
Browser client
React/Vite app for the collaborative editor UI and room navigation.
- App shell · Top-level client bootstrap and routing container.
client/src/App.jsx - Pages · Landing, room, and auth callback screens.
client/src/pages - Editor · Main in-room editing surface and collaboration controls.
client/src/components/Editor.jsx - Toolbar · Room and language actions for the editor room.
client/src/components/Toolbar.jsx - Sidebar · Room info and collaborator list UI.
client/src/components/Sidebar.jsx - Status bar · Cursor, connection, and runtime status display.
client/src/components/StatusBar.jsx - History panel · Saved snapshot history and restore actions.
client/src/components/HistoryPanel.jsx - Yjs hook · Initializes the shared Yjs document and websocket connection.
client/src/hooks/useYjs.js - Awareness hook · Manages ephemeral usernames, cursors, and colors.
client/src/hooks/useAwareness.js - API client · Browser-side REST calls for auth and room operations.
client/src/services/api.js
REST API
Express HTTP service for auth, rooms, and snapshots.
- Express server · REST entry point for authentication and room metadata.
server/index.js - Auth routes · Registration, login, JWT issuance, and OAuth flows.
server/routes/auth.js - Room routes · Room creation, lookup, and snapshot history APIs.
server/routes/rooms.js - JWT guard · Protects private endpoints with JWT verification.
server/middleware/auth.js - DB access · Server-side database access layer.
server/db.js
Realtime sync
Dedicated Yjs websocket process for document replication and presence.
- Yjs server · Dedicated websocket process that relays Yjs updates.
sync-server/server.js - Persistence · Loads and stores serialized Y.Doc state for fast room hydration.
sync-server/persistence.js
Data stores
Durable and fast persistence layers used by the split backend.
- PostgreSQL · Durable store for users, rooms, and snapshots.
- Redis · Fast persistence layer for live Yjs document state.
Connections 23
- App shell → Pages: routes · App renders the main page views.
- Pages → Editor: room view · Room page mounts the collaborative editor.
- Editor → Toolbar: controls · Editor UI includes room and language actions.
- Editor → Sidebar: collaborators · Editor shell exposes collaborator and room context.
- Editor → Status bar: status · Editor shell shows cursor and connection status.
- Editor → History panel: history · Editor shell surfaces snapshot history.
- Editor → Yjs hook: binds · Editor is driven by the shared Yjs document.
- Sidebar → Awareness hook: presence · Sidebar consumes awareness state for online users.
- Status bar → Awareness hook: presence · Status UI reflects ephemeral collaboration state.
- Yjs hook → Yjs server: ws updates · Browser document syncs edits over websockets.
- Awareness hook → Yjs server: awareness · Presence updates are relayed through the sync server.
- API client → Express server: http · Client talks to the REST API for auth and rooms.
- Express server → Auth routes: mounts · Express mounts authentication routes.
- Express server → Room routes: mounts · Express mounts room and snapshot routes.
- Auth routes → JWT guard: protects · JWT guard secures private auth-adjacent actions.
- Room routes → JWT guard: protects · JWT guard secures room operations.
- Auth routes → DB access: reads/writes · Auth flow persists users and tokens metadata.
- Room routes → DB access: reads/writes · Room and snapshot metadata is stored relationally.
- DB access → PostgreSQL: sql · Server persistence uses PostgreSQL as the durable store.
- Yjs server → Persistence: state · Sync server loads and stores document state.
- Persistence → Redis: cache · Serialized Yjs documents are cached in Redis.
- History panel → Room routes: snapshots · History UI fetches and restores snapshot records via REST.
- Pages → API client: auth/rooms · Pages initiate login, callback handling, and room creation flows.