Skip to content

This project is a fullstack implementation of an Excalidraw-like collaborative whiteboard, built with a modern monorepo architecture for scalability and modularity.

Notifications You must be signed in to change notification settings

sakshamVerma08/Excalidraw

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

33 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Excalidraw Clone ๐ŸŽจ

A real-time collaborative drawing application inspired by Excalidraw. This project is a learning exercise focused on understanding modern full-stack architecture, real-time communication, and monorepo management.

๐Ÿšง Project Status

Work In Progress - Backend prototype complete, frontend development starting soon.

๐ŸŽฏ Project Goals

This is primarily a learning project aimed at mastering:

  • Monorepo architecture with Turborepo
  • Real-time WebSocket communication
  • Advanced TypeScript patterns
  • Database management with Prisma
  • Security best practices
  • Full-stack application development

๐Ÿ—๏ธ Architecture

Turborepo Monorepo

  • Shared Packages: Global packages accessible across all apps
  • Turbo Caching: Optimized build times through intelligent caching
  • Type Safety: Global TypeScript definitions shared across workspace

Tech Stack

Backend:

  • Node.js + Express
  • WebSocket (ws library)
  • Prisma ORM
  • PostgreSQL
  • JWT Authentication

Frontend: (Coming Soon)

  • NextJS
  • TypeScript
  • Canvas API

DevOps:

  • Turborepo
  • TypeScript
  • Docker (planned)

โœจ Features Implemented

Real-time Collaboration

  • WebSocket server for persistent connections
  • Room-based collaboration (join/leave rooms)
  • Real-time shape and drawing data transport
  • Conflict resolution for simultaneous edits

Authentication & Security

  • JWT token-based authentication
  • HTTP server for WebSocket upgrade handshake
  • Cookie security (HttpOnly, Secure flags)
  • XSS protection
  • CSRF protection
  • CORS configuration

Database

  • Prisma schema design
  • Migration management
  • User and Room models
  • Many-to-many relationships for room participants

๐Ÿ”ง Key Learnings

Turborepo & Monorepos

  • How turbo caching works under the hood
  • Creating and managing shared packages
  • Configuring pipeline tasks and dependencies
  • Optimizing build performance

TypeScript

  • Complex type definitions and generics
  • Global type declarations
  • Type safety across monorepo packages
  • Solving intricate type errors

WebSockets

  • Real-time bidirectional communication
  • Room-based architecture
  • State synchronization across clients
  • Connection lifecycle management

Authentication over WebSockets

  • Challenge: WebSocket protocol doesn't support headers like HTTP
  • Solution: Use HTTP server for initial upgrade request
    • Client sends JWT in cookie during HTTP handshake
    • Server verifies JWT before upgrading to WebSocket
    • Authenticated user attached to WebSocket connection

Prisma Migrations

  • Schema versioning and evolution
  • Generating and applying migrations
  • Handling schema changes in development vs production
  • Database relationship modeling

Security

  • XSS Prevention: Sanitizing user inputs, HttpOnly cookies
  • CSRF Protection: Token-based validation
  • Secure Cookies: Secure flag for HTTPS-only transmission
  • CORS: (Upcoming) Cross-origin resource sharing policies

๐Ÿ“ Project Structure

excalidraw-clone/
โ”œโ”€โ”€ apps/
โ”‚   โ”œโ”€โ”€ web/                 # Frontend React app (coming soon)
โ”‚   โ””โ”€โ”€ ws-server/           # WebSocket server
โ”‚       โ”œโ”€โ”€ src/
โ”‚       โ”‚   โ”œโ”€โ”€ index.ts     # Server entry point
โ”‚       โ”‚   โ””โ”€โ”€ handlers/    # WebSocket event handlers
โ”‚       โ””โ”€โ”€ package.json
โ”œโ”€โ”€ packages/
โ”‚   โ”œโ”€โ”€ db/                  # Shared Prisma client
โ”‚   โ”‚   โ”œโ”€โ”€ prisma/
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ schema.prisma
โ”‚   โ”‚   โ””โ”€โ”€ index.ts
โ”‚   โ”œโ”€โ”€ types/               # Shared TypeScript types
โ”‚   โ””โ”€โ”€ config/              # Shared configurations
โ”œโ”€โ”€ turbo.json               # Turborepo configuration
โ””โ”€โ”€ package.json             # Root package.json

๐Ÿš€ Getting Started

Prerequisites

  • Node.js (v18 or higher)
  • PostgreSQL
  • pnpm (recommended) or npm

Installation

  1. Clone the repository
git clone https://github.com/yourusername/excalidraw-clone.git
cd excalidraw-clone
  1. Install dependencies
pnpm install
  1. Set up environment variables
cp .env.example .env
# Edit .env with your configuration

Required environment variables:

DATABASE_URL="postgresql://user:password@localhost:5432/excalidraw"
JWT_SECRET="your-super-secret-jwt-key"
PORT=8080
  1. Run Prisma migrations
pnpm db:migrate
  1. Start the development server
pnpm dev

๐Ÿงช WebSocket API

Connection

// Client connects with JWT in cookie
const ws = new WebSocket('ws://localhost:8080');

Events

Join Room

{
  "type": "join_room",
  "roomId": "room-uuid"
}

Leave Room

{
  "type": "leave_room",
  "roomId": "room-uuid"
}

Send Drawing Data (Coming Soon)

{
  "type": "draw",
  "roomId": "room-uuid",
  "data": {
    "shapes": [...],
    "action": "add|update|delete"
  }
}

๐Ÿ“Š Database Schema

User

model User {
  id       String   @id @default(uuid())
  email    String   @unique
  name     String
  password String
  photo    String?
  rooms    Room[]   @relation("RoomParticipants")
}

Room

model Room {
  id               String   @id @default(uuid())
  name             String
  roomParticipants User[]   @relation("RoomParticipants")
  createdAt        DateTime @default(now())
}

๐Ÿ”ฎ Roadmap

  • Frontend canvas implementation
  • Shape rendering and manipulation
  • Color picker and drawing tools
  • User presence indicators
  • Drawing history and undo/redo
  • Export drawings (PNG, SVG)
  • Collaborative cursor positions
  • Room persistence and sharing
  • Docker deployment setup
  • Performance optimization

๐Ÿ› Known Issues

  • WebSocket reconnection logic not implemented
  • No rate limiting on WebSocket messages
  • Database connection pooling needs optimization
  • Type definitions need cleanup in some areas

๐Ÿ“š What I Learned

This project pushed me way outside my comfort zone. Here are the biggest takeaways:

  1. TypeScript is your friend: Those red squiggly lines were frustrating at first, but they saved me from countless runtime errors.

  2. Monorepos are powerful: Once you understand turbo caching and shared packages, development speed increases dramatically.

  3. WebSocket authentication is tricky: You can't just slap a JWT in the connection. The HTTP upgrade handshake pattern is the way to go.

  4. Security matters from day one: Implementing XSS and CSRF protection early is much easier than retrofitting it later.

  5. Real projects beat tutorials: I learned more debugging WebSocket connections than I did from any course.

๐Ÿค Contributing

This is primarily a learning project, but suggestions and feedback are welcome! Feel free to:

  • Open issues for bugs or questions
  • Submit PRs for improvements
  • Share your own learnings

๐Ÿ“ License

MIT License - feel free to use this for your own learning!

๐Ÿ™ Acknowledgments

  • Inspired by Excalidraw
  • Built while learning from the developer community

Note: This is a work-in-progress learning project, not production-ready software. Use at your own risk!

๐Ÿ“ง Contact

Feel free to reach out if you have questions or want to discuss real-time application architecture!


โญ If this project helps you learn, consider giving it a star!

About

This project is a fullstack implementation of an Excalidraw-like collaborative whiteboard, built with a modern monorepo architecture for scalability and modularity.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •