CanvasSync is a real-time collaborative drawing board built with React, TypeScript, Express, and Socket.IO. Multiple users can join the same room, draw together, see live cursors, and export their work as a PNG.
- Live application: multiplecanva.netlify.app
- Backend health check: multiplecanva-backend.onrender.com/health
- GitHub repository: ogakashog/multipleusercannvas
- Releases: GitHub releases
The frontend is hosted on Netlify and the Express/Socket.IO backend is hosted on Render.
- Real-time collaborative drawing rooms
- Custom or generated room IDs
- Live participant list and cursor positions
- Vector pencil and eraser tools
- Brush color and size controls
- User-specific undo and redo
- Canvas zooming and panning
- Cropped PNG export
- Invite links with clipboard and Web Share support
- Session restoration after refresh
- Responsive dark-mode interface
- Frontend: React 19, TypeScript, Vite, Tailwind CSS, Zustand, Framer Motion
- Backend: Node.js, Express, TypeScript, Socket.IO
- Security and performance: Helmet, CORS, compression, rate limiting
- Deployment: Netlify frontend, Render backend
- Containers: Docker and Docker Compose
.
├── backend/ # Express and Socket.IO server
│ ├── src/
│ │ ├── config/ # Environment configuration
│ │ ├── controllers/ # REST API controllers
│ │ ├── middleware/ # Security and rate limiting
│ │ ├── routes/ # API routes
│ │ ├── socket/ # Socket.IO event handlers
│ │ ├── types/ # Shared backend types
│ │ └── utils/ # In-memory room store
│ ├── Dockerfile
│ └── package.json
├── client/ # React and Vite frontend
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ ├── hooks/ # Canvas and Socket.IO hooks
│ │ ├── pages/ # Landing and board pages
│ │ ├── services/ # Socket.IO client service
│ │ ├── store/ # Zustand state
│ │ ├── types/ # Frontend types
│ │ └── utils/ # Canvas utilities
│ ├── Dockerfile
│ └── package.json
├── docker-compose.yml
├── package.json
└── README.md
- Node.js 20 or newer
- npm 10 or newer
From the repository root:
npm install
npm run bootstrapCreate backend/.env:
PORT=5000
CORS_ORIGIN=http://localhost:5173
NODE_ENV=developmentnpm run dev- Frontend: http://localhost:5173
- Backend: http://localhost:5000
- Health check: http://localhost:5000/health
Connect the GitHub repository and use the main branch.
Base directory: client
Build command: npm run build
Publish directory: dist
Functions directory: netlify/functions
Add these Netlify environment variables for the production build:
VITE_SOCKET_URL=https://multiplecanva-backend.onrender.com
VITE_API_URL=https://multiplecanva-backend.onrender.comAfter changing environment variables, trigger Clear cache and deploy site.
Create a Node Web Service using the main branch:
Root directory: backend
Build command: npm install --include=dev && npm run build
Start command: npm start
Set these environment variables:
NODE_ENV=production
CORS_ORIGIN=https://multiplecanva.netlify.appRender supplies the PORT variable automatically. Verify the service with:
https://multiplecanva-backend.onrender.com/health
GET /health
GET /api/rooms/:roomId/validate
POST /api/rooms/create
Run the complete local stack with:
docker compose up --buildThe client is served on port 80 and the backend runs on port 5000.
- Room data and drawing history are currently stored in memory. Restarting the backend clears active rooms and history.
- The backend must run on a service that supports persistent Socket.IO/WebSocket connections.
- Never commit
.envfiles or production environment values to GitHub.
This project is available for personal and educational use.