A collaborative drawing application that uses CRDT (Conflict-free Replicated Data Type) technology to allow multiple users to draw on the same canvas in real-time. Built with NestJS, TypeScript, Yjs, and React.
- Create or join drawing rooms with unique IDs
- Collaborate in real-time with other users
- CRDT-based synchronization using Yjs
- Adjustable brush color and size
- User presence awareness
- Backend: NestJS, WebSockets, Yjs
- Frontend: React, Vite
- CRDT Implementation: Yjs
client/
- React frontend applicationserver/
- NestJS backend server
- Node.js (v14+)
- npm or yarn
- Clone the repository
- Install dependencies:
# Server
cd server
npm install
# Client
cd ../client
npm install --legacy-peer-deps
Important: Use
--legacy-peer-deps
for client installation because react-canvas-draw has peer dependency conflicts with React 19.
- Start the server:
cd server
npm run start:dev
- Start the client:
cd client
npm run dev
-
Open your browser and navigate to the URL shown in the client terminal (usually http://localhost:5173)
-
Create a new room or join an existing one by entering the room ID
If you experience issues with your drawings, such as unwanted additions or disappearing strokes, try these solutions:
-
Draw at a moderate speed: Very fast strokes can cause synchronization issues.
-
Let strokes complete: Pause briefly between strokes to allow synchronization.
-
Check network connection: Ensure stable network connectivity between clients.
-
Use Clear Canvas when things get out of sync: The Clear Canvas button can reset everyone's view if drawings get corrupted.
-
Refresh browsers: If all else fails, have all users refresh their browsers to re-sync.
This application uses Yjs, a CRDT (Conflict-free Replicated Data Type) framework that allows synchronization of shared data. Key aspects:
- Each drawing action is captured as a CRDT operation
- Operations are merged consistently across clients, regardless of arrival order
- The canvas state is shared through the Y.Doc structure
- WebSockets transmit the canvas updates between clients
- User draws on their canvas
- The drawing is converted to Yjs updates
- Updates are sent to the server
- Server broadcasts to other clients
- Other clients apply updates to their local Yjs documents
- Canvas is updated to reflect the changes
MIT
You can now run the application in an integrated mode where the server serves the client application. This simplifies deployment and allows you to run just a single server process.
# Build both client and server, then start the integrated application
./buildAndStart.sh
This script will:
- Build the client application
- Copy the client build files to the server directory
- Build the server application
- Start the server with the integrated client
After starting in integrated mode, you can access the application at:
http://localhost:3000
You no longer need to run the client separately, as all the client files are served by the NestJS server.