Realtime multiplayer whiteboard built with Next.js, Express, WebSockets, and Prisma in a Turborepo monorepo.
- Product:
https://your-domain.com - Frontend:
https://app.your-domain.com - HTTP API:
https://api.your-domain.com - WebSocket:
wss://ws.your-domain.com
- Demo:
https://www.youtube.com/watch?v=YOUR_VIDEO_ID
- MP4:
./docs/assets/demo.mp4
- Realtime collaborative drawing rooms
- Shape tools, text, freehand pencil, erase
- Selection, drag, resize handles, corner resize
- Zoom/pan, keyboard shortcuts, undo/redo
- Export: PNG, SVG, JSON
- Import: JSON
- Private rooms with invite code flow
- Frontend: Next.js (App Router), React, Tailwind CSS
- UI Package: shared
@repo/ui - HTTP Backend: Express + JWT auth
- Realtime Backend:
wsWebSocket server - Database: PostgreSQL + Prisma
- Monorepo: Turborepo + pnpm workspaces
- Validation: Zod
- Testing: Vitest (schema and auth coverage baseline)
apps/
excelidraw-frontend/ # Next.js app
http-backend/ # REST API server
ws-backend/ # WebSocket realtime server
packages/
common/ # Shared zod schemas + common utilities
db/ # Prisma schema/client
ui/ # Shared UI components
DATABASE_URL(Supabase: use the Postgres URI from Connect → Postgres, often the Session pooler on Mac, with?sslmode=require)JWT_SECRETNODE_ENVHTTP_BACKEND_INTERNAL_URL(where Next proxies/api/backend/*; defaulthttp://127.0.0.1:3001)
NEXT_PUBLIC_HTTP_URL(defaulthttp://127.0.0.1:3000/api/backend— same origin as Next)NEXT_PUBLIC_WS_URLNEXT_PUBLIC_ENABLE_LIVE_DEMO(falseto hide demo CTA)
JWT_SECRET(same value in HTTP and WS services)
pnpm installdocker compose up -dPostgres uses host port 5433 (see docker-compose.yml) to avoid clashing with another Postgres on 5432. Match DATABASE_URL in root .env.
pnpm --filter @repo/db exec prisma migrate dev
pnpm --filter @repo/db exec prisma generatepnpm devDefault local endpoints:
- App (Next.js):
http://127.0.0.1:3000— REST is proxied at/api/backend/*to http-backend - HTTP API (direct, optional):
http://127.0.0.1:3001— setHTTP_BACKEND_INTERNAL_URLif you change this port - WS:
ws://localhost:8080
From repo root:
pnpm dev- run all services in devpnpm build- build all workspacespnpm lint- lint all workspacespnpm test- run baseline tests (packages/common,apps/ws-backend)
Package-level examples:
pnpm --dir apps/excelidraw-frontend run check-typespnpm --dir apps/excelidraw-frontend run lintpnpm --dir apps/http-backend run buildpnpm --dir apps/ws-backend run build
Use RELEASE_CHECKLIST.md as the source of truth before go-live.
Quick commands:
pnpm install
pnpm build
pnpm lint
pnpm test
pnpm --dir packages/db prisma migrate deployPOST /signupPOST /signinPOST /room(auth required)GET /room/:roomNameGET /user(auth required)
join_roomleave_roomdrawerasecursorresetbulk_drawpresence
- Backend integration tests for room and auth endpoints
- End-to-end collaborative room tests
- Better observability (error tracking + metrics + alerts)
- Deployment templates for Docker/K8s
Set your license here.
