all projects

projects / 08

drawx

real-time collaborative whiteboard

2nd of 60+ teams · college software exhibition
typescript · 2025 · realtime
cachedbdraw-updateroom/x7k2peercache in front?youyep, drawing it
fig.08 — shared room over a ticketed websocketlive

A real-time collaborative whiteboard. Users sign in with Google, create or join rooms by slug, and draw rectangles, circles, lines, arrows, text and freehand strokes together while chatting. Rooms and strokes persist in Postgres, so anyone can rejoin a board later.

ws ticket lifetime
5min
ws ticket lifetime
msg limit per conn
50/s
msg limit per conn
heartbeat
25s
heartbeat

how it works

  1. 01

    Sign in and join

    Users sign in with Google through NextAuth and create or join a room by slug. Opening /room/[slug] checks that the room exists.

  2. 02

    Get a ticket

    The page asks /api/ws-token for a ticket: an HS256 JWT valid for 5 minutes that binds the user, the room and their role, with the admin role looked up in the database.

  3. 03

    Connect

    The WebSocket server verifies the ticket and the origin before accepting the socket, then tells the room who is connected.

  4. 04

    Draw and chat

    Shapes (rect, circle, line, arrow, text, pencil), erases and chat messages are validated and relayed to everyone in the room. Chat sender identity is stamped by the server.

  5. 05

    Persist

    Whoever draws or erases a stroke saves it through a debounced, batched queue that retries server errors and flushes when the tab closes, so the board doesn't depend on the admin being online.

design decisions

Short-lived tickets for sockets

The WebSocket server is a separate service. A signed 5-minute ticket lets it trust identity and room access without sharing the web app's session store.

Writers persist their own strokes

Saving from the client that made the change means no single participant has to stay online for the board to be saved.

Limits on both sides

1 MiB per message, 50 messages per second per connection, and shape validation on both the socket and the save API keep one client from flooding a room.

highlights

  • 5-minute signed tickets bind user, room and admin role before a socket is accepted
  • Reconnects with a fresh ticket and backoff, re-syncs missed strokes, blocks drawing while offline
  • 1 MiB message cap and 50 msg/s per connection, shapes validated on both the socket and save API

stack

  • next.js
  • ws
  • postgres
  • prisma
  • nextauth
  • turborepo

Building something on the backend? Say hi.

© 2026 Avichal Pandey

ping me··

try: curl -L avichal.me