Back to Projects

SheetSketch

Real-Time Collaboration5 min read

Password-protected multiplayer whiteboard — Liveblocks sync, live cursors, laser pointer, in-room chat, invite links, AI diagram draw, PNG/SVG export. Next.js, Rough.js, Upstash Redis.

SheetSketch - Image 1
Real-Time Collaboration
1 / 1

The Problem

Teams and students need a fast, reliable collaborative whiteboard, but most options are either too heavy (desktop installs, mandatory accounts), too open (no privacy controls), or too limited (no live cursors, chat, laser pointer, or export). Pure Excalidraw clones often skip secure room workflows, invite links with expiry, and AI-assisted diagram generation from natural language.

The gap is a **browser-native, password-protected multiplayer canvas** — hand-drawn Rough.js aesthetic, Liveblocks realtime sync, presentation laser mode, copy/paste shapes, in-room chat, PNG/SVG export, and optional AI draw — without requiring users to sign up for a SaaS account before collaborating.

My Role & Constraints

Solo Full-Stack Engineer & Product Owner — I built SheetSketch end-to-end.

**Frontend:** Next.js 16 App Router — marketing landing (features, how-to-use, FAQ, testimonials, light/dark theme), Get Started room create/join flow, /room/[roomId] collaborative editor, /invite/[token] guest onboarding. Canvas shell: left toolbar (select, rectangle, ellipse, line, arrow, pencil, eraser, text), property inspector (stroke, fill, roughness, opacity, font), infinite pan/zoom, collaborative undo/redo, export menu.

**Realtime:** Liveblocks RoomProvider for shape storage, chat messages, presence (live cursors, laser trails, pointer mode). Custom hooks: useCanvasEvents, useRoomPresence, useShapeClipboard, useChatUnread.

**Backend (API routes):** POST /api/rooms create (bcrypt password → Upstash Redis), POST /api/rooms/{id}/join verify, POST /api/liveblocks-auth JWT validation + session token, invite CRUD (/api/invite/* — 7-day TTL tokens), POST /api/ai-draw OpenAI with Groq fallback.

**Rendering & export:** Rough.js hand-drawn renderer (rough-renderer.ts), off-screen canvas PNG blob export, SVG document builder (canvas-export.ts) — full board or selection only.

**AI:** Natural-language prompt → LLM returns validated shape JSON → addShapes Liveblocks mutation injects flowcharts/diagrams onto visible canvas bounds.

System Design / Architecture

SheetSketch is a **Next.js full-stack app** — React client + API routes + external realtime/Redis/LLM services. No separate Express server.

**Topology:**
1$Browser → Next.js pages + API routes
2$ → Upstash Redis (room passwords, invite tokens)
3$ → Liveblocks Cloud (shapes, chat, presence)
4$ → OpenAI / Groq (AI draw, optional)

**Room access flow:** 1. User enters roomId + password on Get Started 2. POST /api/rooms (create) or /join (verify bcrypt hash in Redis) 3. API signs JWT (room_access, 24h expiry) → sessionStorage 4. Redirect /room/{roomId} → Liveblocks auth handler verifies JWT matches roomId → grants room:write

**Invite flow:** 1. Host clicks Invite (Bearer JWT) → POST /api/rooms/{id}/invite → Redis invite:{token} TTL 7 days 2. Guest opens /invite/{token} → enters name + room password → join API → JWT → redirect to room 3. Stable guest_id per browser for presence/chat identity

**Collaboration sync:** - **Storage:** Liveblocks list of shapes (rectangles, ellipses, lines, arrows, freehand, text) — mutations broadcast to all clients - **Presence:** cursor x/y, userName, color, pointerMode, laserTrail[] for presentation mode - **Chat:** messages array in storage; unread badge when panel closed

**Laser pointer:** Toggle K or toolbar — hides default cursor, draws colored trails on AppleLaserLayer overlay synced via presence; Esc disables

**AI draw flow:** User prompt + visible canvas bounds → /api/ai-draw → system prompt constrains JSON shape schema → parse/validate → client mutation pushes shapes into Liveblocks storage

**Security:** bcrypt room passwords in Redis (never plaintext); JWT room binding enforced in Liveblocks auth; invite tokens expire; env secrets not committed.

Key Engineering Decisions

  • •Liveblocks as realtime backbone — deterministic multiplayer sync for shapes, chat, and presence without building custom OT/CRDT infrastructure.
  • •Upstash Redis for room metadata only — passwords (bcrypt) and invite tokens; Liveblocks holds all canvas state (separation of auth metadata vs drawing data).
  • •JWT in sessionStorage (24h) after password verify — stateless room access for Liveblocks auth handler without server sessions.
  • •Rough.js rendering layer — hand-drawn aesthetic differentiated from sterile vector tools; matches Excalidraw-category UX expectations.
  • •Laser pointer as presence overlay (not shapes) — presentation trails don't pollute undo history or export output.
  • •OpenAI primary + Groq fallback for AI draw — resilience when OpenAI quota/billing blocks requests.
  • •Copy/paste/duplicate with offset helpers (`shape-clipboard.ts`) — standard `Ctrl/Cmd+C/V/D` UX for shape editing.
  • •Export pipeline renders off-screen canvas — PNG via `toBlob`, SVG via `buildSvgDocument`; supports selection-only export for docs/slides.
  • •Password required even on invite join — invite link alone is not enough; guest must know room password (defense in depth).

Business / Product Thinking

SheetSketch targets **frictionless workshop collaboration** — design reviews, classroom brainstorming, portfolio demos. Positioning: *create a room → share link → draw together → export PNG/SVG* — zero install, password-private.

**Product-led loop:** landing CTA → Get Started → create design-review room → invite teammate via 7-day link → live cursors + laser walkthrough → export diagram to Notion/Slides.

**Go-to-market:** live at sheet-sketch.vercel.app → GitHub with Mermaid architecture + sequence diagrams in README → Figma/Excalidraw-adjacent communities.

**Monetization paths (not shipped):** premium room retention, org workspaces, AI draw quotas, view-only invite roles, room templates (flowchart, retro, wireframe).

Results & Impact

Live at sheet-sketch.vercel.app with source at github.com/subhm2004/SheetSketch.

**Shipped (canvas):** rectangles · ellipses · lines · arrows · freehand · text boxes (T + double-click) · select/move/resize/delete · property inspector · pan/zoom · collaborative undo/redo · copy/paste/duplicate (Ctrl/Cmd+C/V/D).

**Shipped (collaboration):** Liveblocks realtime sync · live cursors with names/colors · **laser pointer** (K, collaborative trails) · toggle other users' cursors · in-room chat with unread badge · presence avatars + active user count.

**Shipped (access):** password-protected rooms (bcrypt + Redis) · JWT session (24h) · **invite links** (7-day TTL, name + password join) · guest identity per browser.

**Shipped (platform):** AI diagram generation (OpenAI/Groq) · PNG + SVG export (full or selection) · marketing landing + light/dark theme · keyboard shortcuts · Turbopack dev · Vercel deploy · documented 6 sequence diagrams in README.

What I'd Do Differently

JSON export + session restore would let users reload complex boards without Liveblocks history limits. In-app shortcut panel (?) and view-only invite roles for enterprise workshop control. Enhanced mobile touch targets for tablet sketching. Room templates (flowchart, retro, wireframe) would speed AI draw prompts. Rate limiting on AI draw endpoint to control LLM costs on public deploy.

Tech Stack

Next.js
TypeScript
Tailwind CSS
Liveblocks
WebSockets
Docker
JavaScript
GitHub

Want to see more?

View All Projects