
</collab dashboard>
Real-time collaborative whiteboard with 50–80ms sync.
50–80 ms
sync latency
4 tiers
roles · 30+ permission flags
60 fps
dirty-region canvas rendering
SPECIFICATIONS
| ROLE | SOLO BUILD |
|---|---|
| YEAR | 2025 |
| TYPE | WEB APP |
| STATUS | archive |
| STACK | react · socket.io · node.js · express · canvas-api · vite |
| LINKS | [github ↗] |
| AVAILABILITY | in development |
“Shared whiteboards live or die on latency.”
A real-time collaborative whiteboard with sub-100ms latency.Multiple users draw, diagram, and annotate simultaneously with live cursor tracking, layered canvas, AI-powered shape recognition, role-based permissions, and threaded comments, all synced over WebSockets.
== WHAT IS THIS ==
A real-time collaborative whiteboard with sub-100ms latency. Multiple users draw, diagram, and annotate simultaneously with live cursor tracking, layered canvas, AI-powered shape recognition, role-based permissions, and threaded comments, all synced over WebSockets.
== </the problem> ==
Shared whiteboards live or die on latency. Past ~100ms of sync lag, remote collaboration stops feeling like a shared room and starts feeling like taking turns. Most canvas tools also treat access control as an afterthought — everyone is either a full editor or locked out entirely, which breaks down the moment a real team uses the board.
== </my approach> ==
Built the rendering pipeline on the raw Canvas API with dirty-region tracking, so only changed areas re-render inside a 60fps requestAnimationFrame loop. Sync runs over Socket.io: clients emit drawing actions, text operations, cursor movements, and history commands; the server validates each against the user's role, stores the change, and broadcasts to all session participants. A central state manager handles undo/redo history, layer composition, and conflict resolution when multiple users edit the same element.
== </the story> ==
Collab Dashboard started as a question about latency: how fast can you make a shared canvas feel like everyone's in the same room? The answer was sub-100ms, typically 50-80ms on a local network.
The app is a full collaborative whiteboard: freehand drawing with customisable brushes, geometric shapes, flowchart and UML smart shapes, text annotations with formatting, and a layer system with visibility toggling and reorder. An AI-powered shape recognition engine snaps rough sketches into clean geometric forms. Draw a wobbly circle and it locks to a perfect one.
Five pre-built templates ship out of the box: flowcharts, Kanban boards, mobile wireframes, sequence diagrams, and mind maps. Users can embed YouTube and Vimeo videos directly onto the canvas, and export their boards as PNG, SVG, or JSON.
The collaboration layer is where it gets interesting. Every connected user has a live cursor with presence indicators showing where they're actively drawing. A threaded comment system supports resolve/unresolve workflows. An activity log timestamps every session event. Toast notifications surface user joins, role changes, and permission updates in real time.
== </architecture> ==
The frontend runs React 19 with Vite 7, using the Canvas API for all rendering with requestAnimationFrame for 60fps draw loops. Dirty state tracking ensures only changed regions re-render. No full-canvas redraws on every frame.
The backend is Node.js 22 with Express 5 and Socket.io 4. The WebSocket event flow is bidirectional: clients emit drawing actions, text operations, cursor movements, and history commands. The server validates permissions against the user's role, stores the change, then broadcasts to all session participants.
The role and permission system has four tiers (Creator, Editor, Viewer, and Commenter) with 30+ granular permission flags that can be overridden per-user. Permissions scope down to individual shapes and layers, so a Creator can lock specific elements while leaving the rest editable.
Canvas operations flow through a central state manager that handles undo/redo history, layer composition, and conflict resolution when multiple users edit the same element simultaneously.
== </key features> ==
Sub-100ms sync
Typically 50–80ms latency on a local network. Bidirectional WebSocket events push drawing actions, cursors, and history commands with server-side permission validation on every change.
Live presence layer
Every connected user has a live cursor with presence indicators showing where they're actively drawing, plus toast notifications for joins, role changes, and permission updates.
AI shape recognition
Draw a wobbly circle and it locks to a perfect one. Rough sketches snap into clean geometric forms, flowchart shapes, and UML elements.
Four-tier permission system
Creator, Editor, Viewer, and Commenter roles with 30+ granular flags, overridable per user and scoped down to individual shapes and layers.
Layers, templates, and export
Layer system with visibility toggling and reorder, five pre-built templates (flowcharts, Kanban, wireframes, sequence diagrams, mind maps), YouTube/Vimeo embeds, and PNG/SVG/JSON export.
Threaded comments + activity log
Comment threads with resolve/unresolve workflows and a timestamped log of every session event.
== </key decisions> ==
DECISION 01
The biggest architectural bet was going with raw Canvas API instead of a library like Fabric.js or Konva. It meant writing more code (shape hit detection, layer compositing, text rendering) but it gave me full control over the rendering pipeline. That control was essential for the performance targets: dirty region tracking and selective re-rendering would have been impossible with an abstracted canvas library.
DECISION 02
Socket.io over raw WebSockets was a pragmatic choice. The automatic reconnection, room management, and event acknowledgement saved weeks of infrastructure work. At the scale this app operates (small teams, not thousands of concurrent users), the Socket.io overhead is negligible.
DECISION 03
The permission system was intentionally over-engineered for the scope of the project. 30+ flags with per-resource scoping is enterprise-grade access control. But building it taught me how real production permission systems work, and it means the app can actually be used in contexts where access control matters.
== </what i learned> ==
Raw Canvas API over Fabric.js or Konva meant writing more code — hit detection, layer compositing, text rendering — but dirty-region tracking and selective re-rendering would have been impossible through an abstracted library.
Socket.io over raw WebSockets was the pragmatic call. Automatic reconnection, room management, and event acknowledgement saved weeks of infrastructure work, and at small-team scale the overhead is negligible.
Deliberately over-engineering the permission system taught me how real production access control works — and it means the app holds up in contexts where access actually matters.
react · socket.io · node.js · express · canvas-api · vite
archive