SyncCanvas is a real-time collaborative visual workspace for system design, diagrams, and team sketching. Multiple users can draw together with live cursor tracking, persistent board history, and secure JWT authentication.
The repository includes Docker-based local development and AWS deployment automation for S3, CloudFront, EC2, and PostgreSQL.
- Real-time Collaboration — Low-latency scene sync via WebSockets; every stroke appears instantly for all participants.
- Live Cursors & Presence — See collaborators' cursors and active-user status in real time.
- Persistent Boards — Board state is stored in PostgreSQL so work is never lost between sessions.
- Version History — Save named snapshots and restore any previous state of a board.
- Secure Auth — JWT-based sign-in and sign-up with protected board routes.
- Viewer Mode — Share a read-only board link via
?role=viewer. - Premium UI — Glassmorphic panels, Inter typography, dark/light theme toggle.
| Layer | Technology |
|---|---|
| Framework | React 18 + Vite |
| Language | TypeScript |
| Styling | Tailwind CSS |
| Icons | Lucide React |
| Whiteboard | Excalidraw |
| Routing | React Router v7 |
| Layer | Technology |
|---|---|
| Runtime | Node.js 20 |
| Framework | Express |
| WebSocket | ws library |
| Auth | JSON Web Tokens (JWT) |
| ORM | Prisma 6 |
| Database | PostgreSQL 16 (Docker) |
| Service | Purpose |
|---|---|
| AWS S3 | Frontend static hosting |
| AWS CloudFront | CDN + HTTPS + API/WS routing |
| AWS EC2 | Backend server (Docker Compose) |
| GitHub Actions | CI/CD pipeline |
Browser (HTTPS)
│
▼
CloudFront ──── / ──► S3 Bucket (React SPA)
(HTTPS CDN) /api/* ──► EC2 nginx ──► Node.js :3000
/ws* ──► EC2 nginx ──► WebSocket Server
│
▼
PostgreSQL (Docker)
All client traffic flows through CloudFront over HTTPS. CloudFront routes API calls and WebSocket connections to the EC2 origin, which runs the Node.js backend and PostgreSQL via Docker Compose.
- Node.js 20+
- Docker & Docker Compose (for PostgreSQL)
git clone https://github.com/Pranjali86/sync-canvas.git
cd sync-canvas
npm installdocker compose up -d dbCreate server/.env:
PORT=3000
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/whiteboard"
JWT_SECRET="your-secret-key-here"
CORS_ORIGINS="http://localhost:5173"Create client/.env:
VITE_API_BASE_URL=http://localhost:3000
VITE_WS_BASE_URL=ws://localhost:3000# Apply schema to local DB
cd server && npx prisma db push && cd ..
# Start backend and frontend in parallel
npm run dev| Service | URL |
|---|---|
| Frontend | http://localhost:5173 |
| Backend API | http://localhost:3000 |
| Health check | http://localhost:3000/health |
The app ships via GitHub Actions on every push to main.
| Secret | Description |
|---|---|
VITE_API_BASE_URL |
CloudFront HTTPS base URL |
VITE_WS_BASE_URL |
CloudFront WSS URL with /ws path |
AWS_ACCESS_KEY_ID |
IAM key with S3 + CloudFront permissions |
AWS_SECRET_ACCESS_KEY |
IAM secret |
AWS_REGION |
e.g. ap-south-1 |
S3_BUCKET_NAME |
Frontend bucket name |
CLOUDFRONT_DISTRIBUTION_ID |
CloudFront distribution ID |
EC2_HOST |
EC2 public IP |
EC2_SSH_KEY |
PEM private key (contents) |
- Frontend job — builds the React app with env vars injected at build time, syncs assets to S3 (long-lived cache), uploads
index.html(no-cache), invalidates CloudFront. - Backend job (runs after frontend) — SSHs into EC2 and runs
docker compose up -d --build --no-deps serverto rebuild only the server container, preserving the PostgreSQL data volume.
DB_PASSWORD=<strong-random-password>
JWT_SECRET=<long-random-secret>
CORS_ORIGINS=https://<your-cloudfront-domain>.cloudfront.netsync-canvas/
├── client/ # React + Vite frontend
│ └── src/
│ ├── components/ # Navbar, ProtectedRoute, CursorLayer …
│ ├── contexts/ # AuthContext, ThemeContext
│ ├── hooks/ # useRoom, useWebSocket …
│ ├── pages/ # Home, BoardPage, LoginPage, SignupPage
│ └── services/ # apiClient, socketProtocol
├── server/ # Node.js + Express backend
│ ├── prisma/ # Schema + migrations
│ └── src/
│ ├── controllers/ # auth, board, health
│ ├── middleware/ # authMiddleware
│ ├── rooms/ # RoomManager
│ ├── services/ # AuthService, DatabaseService
│ └── websocket/ # WebSocketHandler
├── deploy/ # nginx config + EC2 bootstrap script
├── docker-compose.yml # PostgreSQL + server containers
└── .github/workflows/ # CI and deploy pipelines
MIT. SyncCanvas modifications © Pranjali. The original ExcaliLive copyright and MIT permission notice are preserved in LICENSE.