Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

26 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🎨 CollabDraw - Real-time Collaborative Whiteboard

Next.js TypeScript Prisma WebSocket Tailwind CSS

A real-time collaborative whiteboard: create rooms, share a link, and draw together with live user count.

πŸ“Έ Screenshots

🏠 Landing Page

Landing Page

πŸ” Authentication

Authentication

🎨 Drawing Canvas

Drawing Canvas

✨ Features

  • Real-time collaboration across multiple users in the same room
  • Live user count per room
  • Create/join rooms by name (slug) or numeric room ID
  • Drawing tools: pencil (with width), rectangle, circle, eraser
  • Color picker with 16 presets
  • JWT-based auth with bcrypt password hashing

πŸ—οΈ Architecture

β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ excelidraw-frontend/     # Next.js 15 frontend (port 3002)
β”‚   β”œβ”€β”€ http-backend/            # Express REST API   (port 3001)
β”‚   └── ws-backend/              # WebSocket server    (port 8081)
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ db/                      # Prisma schema + client
β”‚   β”œβ”€β”€ common/                  # Shared Zod schemas
β”‚   β”œβ”€β”€ backend-common/          # Shared backend config (JWT_SECRET)
β”‚   β”œβ”€β”€ ui/                      # Shared UI components
β”‚   └── typescript-config/       # Shared tsconfig presets

Backends run directly from TypeScript via tsx β€” no compile step required for local dev.

πŸ› οΈ Technology Stack

Frontend: Next.js 15, React 19, TypeScript, Tailwind CSS, HTML5 Canvas Backend: Express, ws, JWT, bcrypt Database: PostgreSQL via Prisma Monorepo: Turborepo + npm workspaces (tsx for backends)

πŸš€ Quick Start

Prerequisites

  • Node.js β‰₯ 18
  • npm (bundled with Node) β€” do not use pnpm/yarn; only npm is supported
  • A reachable PostgreSQL instance

1. Install dependencies

From the repo root:

npm install

This installs every workspace (frontend, backends, shared packages) at once.

2. Configure environment variables

Copy the example env files and fill in real values.

cp packages/db/.env.example           packages/db/.env
cp apps/http-backend/.env.example     apps/http-backend/.env
cp apps/ws-backend/.env.example       apps/ws-backend/.env
cp apps/excelidraw-frontend/.env.example apps/excelidraw-frontend/.env.local

On Windows PowerShell, use copy instead of cp.

Required values:

File Variables
packages/db/.env DATABASE_URL
apps/http-backend/.env PORT (3001), JWT_SECRET, DATABASE_URL
apps/ws-backend/.env PORT (8081), JWT_SECRET, DATABASE_URL
apps/excelidraw-frontend/.env.local NEXT_PUBLIC_HTTP_BACKEND, NEXT_PUBLIC_WS_URL

Important: JWT_SECRET must match between http-backend and ws-backend. There is no insecure fallback β€” missing JWT_SECRET will crash the backend on startup.

3. Initialize the database

npm run db:generate   # generate Prisma client
npm run db:push       # push schema to your Postgres database

4. Start everything in dev mode

npm run dev

Turbo starts all three services with file watching:

To stop: Ctrl+C in the terminal.

Optional: start individual services

npm run dev --workspace=excelidraw-frontend
npm run dev --workspace=http-backend
npm run dev --workspace=ws-backend

πŸ“± How to Use

  1. Go to http://localhost:3002 and sign up.
  2. Sign in; you'll be redirected to the Rooms page.
  3. Create New Room β†’ enter a name β†’ redirected to /canvas/<roomId>.
  4. Share the room ID (or slug) with another user; they can use Join by ID or Join by Link.
  5. Draw together β€” the user count bottom-center reflects everyone connected.

Drawing Tools

  • Pencil β€” freehand, adjustable width
  • Rectangle β€” click-drag
  • Circle β€” click-drag
  • Eraser β€” click a shape to remove it
  • Color Picker β€” 16 presets

πŸ”§ Available Scripts (root)

npm run dev           # Run all apps in dev (Turborepo)
npm run build         # Build all apps that have a build script (frontend)
npm run lint          # Lint workspaces that have a lint script
npm run format        # Prettier format
npm run db:generate   # Prisma generate
npm run db:push       # Prisma db push
npm run db:migrate    # Prisma migrate dev

πŸ”’ Security Notes

  • Passwords are hashed with bcrypt (10 rounds) before storage.
  • JWT_SECRET must be set; the backend refuses to boot without it.
  • WebSocket connections are authenticated by a ?token=<jwt> query parameter.
  • JWT verification is wrapped in try/catch β€” invalid/expired tokens return 403 instead of crashing the server.

πŸ“„ API

Auth

POST /signup { username, password, name }  β†’ { userId }
POST /signin { username, password }        β†’ { token }

Rooms

POST /room       (auth required) { name } β†’ { roomId }
GET  /room/:slug                          β†’ { room }
GET  /room/id/:id                         β†’ { room }
GET  /chats/:roomId                       β†’ { messages }

WebSocket (ws://…:8081?token=<jwt>)

// client β†’ server
{ type: "join_room", roomId }
{ type: "leave_room", roomId }
{ type: "chat", roomId, message }   // carries drawing add/delete payload

// server β†’ client
{ type: "user_count", roomId, count, users }
{ type: "chat", roomId, message, userId }

Drawing shapes are sent as chat messages with JSON payloads { action: "add" | "delete", … } so that history can be rebuilt on reconnect via GET /chats/:roomId.

🧩 Troubleshooting

  • JWT_SECRET is not set β€” create apps/http-backend/.env and apps/ws-backend/.env from the examples.
  • Can't reach database server β€” verify DATABASE_URL in every .env that needs it (db package, http-backend, ws-backend) and that Postgres is running.
  • Port already in use β€” override PORT in the relevant .env, and update the frontend's NEXT_PUBLIC_HTTP_BACKEND / NEXT_PUBLIC_WS_URL accordingly.
  • Changes to shared packages don't reflect β€” backends watch their own src/; shared packages are loaded at import time. Restart the affected backend if you edit packages/common or packages/backend-common.

πŸ“ž Contact

About

Real-time collaborative whiteboard built with a Turborepo monorepo: Next.js frontend, Express API, WebSocket server, shared UI package, and PostgreSQL database. Designed for low-latency sync, clean architecture, and scalable real-time collaboration.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages