Multi-user drawing board based on tldraw with authentication and real-time synchronization.
- ✅ User registration/login
- ✅ Create and manage boards
- ✅ Real-time collaboration via WebSocket
- ✅ Display connected users
- ✅ Collaborative board editing
- ✅ Share via links
- ✅ Roles: admin / user
- ✅ SQLite for data storage
- ✅ 📝 Custom stickers with clone handles
- ✅ 🔗 Arrows follow moved stickers
- ✅ 🎨 Color picker for stickers
# Terminal 1 - Server
cd server
bun install
bun run start
# Terminal 2 - Client
cd client
bun install
bun run devAccess:
- Client: http://localhost:3000
- Server: http://localhost:3001
# Build and export rootfs to tar.gz
./export-images.sh
# Or step by step:
./build.sh # Build to prod/
docker build --output ./server-rootfs ./prod/server
docker build --output ./client-rootfs ./prod/clientRun:
# Run via docker (import from rootfs)
docker import privateboard-server.tar privateboard-server:latest
docker import privateboard-client.tar privateboard-client:latest
docker run -d --name privateboard-server -p 3001:3001 -v privateboard_data:/app/data -e JWT_SECRET=your-secret privateboard-server
docker run -d --name privateboard-client -p 80:80 --link privateboard-server:server privateboard-clientOr run without Docker (from rootfs):
# Extract
tar -xzf privateboard-server.tar.gz
cd server-rootfs
# Run server (bun required)
bun run start
# Client needs nginx
# Copy files from client-rootfs to /usr/share/nginx/html| Component | Technology |
|---|---|
| Frontend | React + Vite + tldraw v3 |
| Backend | Node.js + Express + Bun runtime |
| Database | SQLite |
| Real-time | WebSocket (ws) |
| Auth | JWT |
| Docker | Alpine + nginx |
- Click the Note button in the left toolbar
- Click on the canvas — a yellow 200x200 sticker appears
- Click on the text to edit
- Select the sticker
- A Color picker will appear in the top right panel
- Choose a color (yellow, green, blue, red, violet, orange)
- Create a sticker and select it
- 4 handle dots will appear on the edges (right, bottom, left, top)
- Pull any dot — the following will be automatically created:
- Arrow from the center of the first sticker
- New sticker of the same color
- Binding: arrow is bound to the new sticker
- After releasing, the create mode for a new sticker will automatically activate
- When moving the sticker, the arrow follows it
You can also use the built-in arrow:
- Press A or select Arrow in the bottom panel
- Drag from one object to another
- Arrow will bind to the edges of shapes
The application uses WebSocket for instant synchronization of changes between users:
- When opening a board, the client connects to the WebSocket server
- All changes (drawing, moving objects, stickers) are broadcast to other users
- Connected user names are displayed in the editor header
To enable WebSocket logs, change in client/src/App.jsx:
const DEBUG_WS = true // was: falseAfter this, the browser console will show:
- WebSocket connect/disconnect
- User join/leave
POST /api/auth/login— loginPOST /api/auth/register— registrationGET /api/auth/me— current user
GET /api/boards— list boardsPOST /api/boards— create boardGET /api/boards/:id— get boardPUT /api/boards/:id— save boardDELETE /api/boards/:id— delete board
ws://localhost:3001/ws— WebSocket endpoint
Messages:
join— join board roomleave— leave roomchange— send snapshot changesusers-list— list of users in roomuser-joined— user joineduser-left— user left
Frontend:
- React 18
- tldraw 3
- React Router
- Axios
- WebSocket API
Backend:
- Node.js + Express
- SQLite3
- JWT for authentication
- WebSocket (ws)
Admin: admin / admin
- Rust migration — rewrite server in Rust (Axum/Actix + Tokio)
- Performance and memory safety
- Lower resource consumption
- Type-safe APIs
- Switch from SQLite to PostgreSQL
- Scalability
- Concurrent access
- Advanced features (triggers, views)
- Redis for sessions and caching
- gRPC for internal communication
- More graphic components
- Tables / data grids
- Diagrams (flowchart, mind map)
- Frames with collaboration
- Text documents
- Code blocks with syntax highlighting
- Refactor App.jsx — split 1852 lines into components
- TypeScript — full migration from .jsx to .tsx
- CSS Modules / Tailwind — replace inline styles
- Tests — Vitest + React Testing Library
- Board sharing — public/private, link access
- Comments — discuss board elements
- Change history — rollback to previous versions
- Export — PNG, SVG, PDF
- Templates — ready-made board layouts
- PrivateBoard code is distributed under the GNU Lesser General Public License v3.0 (LGPL‑3.0).
- The project uses tldraw components, which are distributed under the tldraw license.
Using tldraw components in Production Environments (public services, commercial products) requires obtaining a separate commercial license from tldraw Inc..
This repository is intended for:
- internal use in organizations;
- development and testing;
- local deployment.
For commercial use of PrivateBoard with tldraw components, contact tldraw Sales. see tldraw/tldraw#8248