This document provides an overview of the applications within this monorepo, which together form a full-stack collaborative whiteboarding application.
This project is a real-time, collaborative whiteboarding application, similar to Excalidraw. It allows multiple users to join a "room" and draw together on a shared canvas. The application state, including all drawings, is persisted in a database and synchronized across all clients in real-time using WebSockets.
The project is structured as a monorepo with separate packages for the frontend, the HTTP backend, and the WebSocket backend.
The apps directory contains the core applications of the project:
excelidraw-frontend/: The main frontend application built with Next.js. It provides the user interface for drawing, authentication, and the landing page.http-backend/: An Express.js server that handles RESTful API requests for user authentication, room management, and fetching historical drawing data.ws-backend/: A Node.js WebSocket server responsible for real-time communication between clients. It broadcasts drawing actions to all users in a specific room.web/: A secondary, simpler Next.js application that appears to be a basic chat client, demonstrating the use of the WebSocket backend for text-based chat.
Based on the excelidraw-frontend application:
- Real-time Collaboration: Work with your team on the same canvas.
- Multiplayer Editing: See other users' drawings as they happen.
- Drawing Tools: Includes basic tools like Pencil, Rectangle, and Circle.
- Room-based Sessions: Collaboration happens in unique, shareable rooms.
- Persistent Drawings: Drawings are saved and reloaded when you rejoin a room.
- User Authentication: A basic JWT-based authentication system for user signup and signin.
-
Frontend (
excelidraw-frontend):- Framework: Next.js
- Language: TypeScript
- Styling: Tailwind CSS
- UI Components: lucide-react (for icons)
- Data Fetching: axios
-
Backend (HTTP):
- Framework: Express.js
- Language: TypeScript
- Authentication: JSON Web Tokens (JWT)
- ORM: Prisma
-
Backend (WebSocket):
- Library:
ws(A native WebSocket library for Node.js) - Language: TypeScript
- Authentication: JSON Web Tokens (JWT)
- Library:
-
Database:
- A relational database managed via Prisma Client.
- Node.js (v18 or higher recommended)
- A package manager like
npm,yarn, orpnpm - A running database instance (e.g., PostgreSQL, MySQL) configured for Prisma.
- Clone the repository.
- Navigate to the root of the monorepo.
- Install all dependencies for all workspaces (e.g.,
npm installoryarn install). - Set up your database and create a
.envfile in the@repo/dbpackage (or as required by your setup) with theDATABASE_URL. - Run Prisma migrations to set up the database schema:
npx prisma migrate dev. - Create
.envfiles in the respective backend packages (http-backend,ws-backend) for environment variables likeJWT_SECRET. - In
excelidraw-frontend/config.ts, ensureHTTP_BACKENDandWS_URLpoint to the correct backend addresses.
Each application can be run concurrently from its own directory. Open separate terminal windows for each service.
1. Start the HTTP Backend:
cd apps/http-backend
npm install
npm run dev
# Server will start on http://localhost:30012. Start the WebSocket Backend:
cd apps/ws-backend
npm install
npm run dev
# WebSocket server will start on ws://localhost:80803. Start the Frontend:
cd apps/excelidraw-frontend
npm install
npm run dev
# Frontend will be available at http://localhost:3000The http-backend service exposes the following REST endpoints:
POST /signup: Creates a new user.- Body:
{ "username": "...", "password": "...", "name": "..." }
- Body:
POST /signin: Authenticates a user and returns a JWT.- Body:
{ "username": "...", "password": "..." }
- Body:
POST /room: Creates a new drawing room. (Requires authentication token in header).- Body:
{ "name": "..." }
- Body:
GET /chats/:roomId: Retrieves all saved shapes (messages) for a given room ID.GET /room/:slug: Retrieves room details using its unique slug.
The ws-backend handles real-time events.
Connection:
A client must connect to ws://localhost:8080 with a valid JWT provided as a query parameter.
ws://localhost:8080?token=<YOUR_JWT_TOKEN>
Messages (Client to Server):
- Join Room:
{ "type": "join_room", "roomId": "your_room_id" } - Send Shape/Drawing Data: The application uses a message type of
"chat"to send drawing data. Themessagefield is a stringified JSON object representing the shape.{ "type": "chat", "roomId": "your_room_id", "message": "{\"shape\":{\"type\":\"rect\",\"x\":100,\"y\":100,\"width\":50,\"height\":50}}" }
Messages (Server to Client):
- Broadcast Shape/Drawing Data: When a user draws something, the server broadcasts it to all other users in the same room.
{ "type": "chat", "roomId": "your_room_id", "message": "{\"shape\":{\"type\":\"rect\",\"x\":100,\"y\":100,\"width\":50,\"height\":50}}" }