Real-time collaborative whiteboard for your LAN. Sticky notes, text labels, and multi-board organization, synced live between everyone who has the page open. The whole frontend is one dependency-free HTML file; the server is a single Node script with ws as its only package.
- Sticky notes — click to add, drag to move, resize, recolor (preset palette or any hex), bold toggle, inline editing with live sync while someone else types.
- Text labels — lightweight headings for structuring the board.
- Multiple boards + folders — create, rename, and organize boards into folders; each board is its own synced room.
- Multiplayer — live peer cursors with names and colors, editing/dragging indicators, online count. Profiles are remembered per IP, so nobody logs in twice.
- Select tool — rubber-band multi-select, group drag, group delete, undo.
- Persistence — full state is debounce-saved to
state.json; restart the server and everything is still there. - Dark/light theme, import from JSON, connection-status indicator with auto-reconnect, and a built-in debug panel showing message stats and peers.
npm install
npm startOpen http://localhost:3000. The server prints your LAN addresses on startup — anyone on the same network can join at http://<your-ip>:3000 (phones included; it works fine on mobile).
On Windows, start.bat does the same thing.
server.jsserves the static page on port 3000 and runs a WebSocket hub on port 1234.- Clients send granular updates (
set/deleteper note, cursor moves, board/folder operations); the server applies them to in-memory state, rebroadcasts to the other clients in the same board room, and debounce-writesstate.json. - New clients get a full
initsnapshot of their board plus the board/folder list, so joining is instant.
Ports live at the top of server.js (PORT, WS_PORT) if you need to change them.
index.html— the entire client: styles, canvas-free DOM rendering, tools, sync logicserver.js— static file server + WebSocket state hub + persistencestate.json— created at runtime; your boards (gitignored)
