This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady
What I Built
DrawBoard is a real-time collaborative whiteboard — sketch, diagram, and think together in the browser, with live shape sync, room-based access control, and in-board chat.
But the laziness story runs on two levels.
For users: DrawBoard rewards the lazy visitor. You open the /canvas/guest page and you're drawing — no signup, no email, no onboarding wizard. One share link and anyone can join your board. When you're done, export the whole thing as PNG or SVG instead of screenshotting your sketch in four torn pieces. Keyboard shortcuts for every tool (V for select, P for pencil, Ctrl+K for the command palette) mean your hands never leave home row.
For me: the honest confession is that the sloth was the developer. I wanted a collaborative whiteboard for my own project discussions — Excalidraw-style, but the kind I fully understand because I built it. Setting aside weekend after weekend to hand-write a canvas engine, a WebSocket sync layer, and an auth flow across three services was exactly the task I kept putting off. So I didn't do it myself. An open-source AI agent did the heavy lifting, reviewed every plan with me, and I shipped the whole thing in the challenge window instead of someday/Maybe Land. Every file in this repo started as a conversation with an agent running an open-weight model.
Demo
▶️ Video demo: Watch DrawBoard in action (Google Drive)
🌐 Live app: drawboard-peach.vercel.app
The guest board at /canvas/guest is the fastest way in — no account needed. Create a room as a signed-in user, share the link, and watch shapes sync in real time.
Code
🎨 Drawboard
A real-time collaborative whiteboard. Sketch, diagram, and think together — right in the browser.
🌐 Live demo: drawboard-peach.vercel.app 📦 Repository: github.com/Tusharkhadde/Excalidraw
Overview
Drawboard is a collaborative whiteboard built as a pnpm + Turborepo monorepo with three services:
- Next.js frontend — landing page, auth, workspace dashboard, and the canvas board
- Express HTTP API — auth, rooms, room access requests, chat history
- WebSocket server — live drawing sync + in-room chat
Data is stored in PostgreSQL via Prisma. You can draw as a guest (no account), or sign up to create shared rooms, request/approve access, chat while drawing, and export the board.
Table of contents
- Tech stack
- Features
- Getting started
- Environment variables
- Scripts
- Architecture
- API reference
- WebSocket messages
- Database
- Deployment
- License
Tech stack
| Layer | Technology |
|---|---|
| Monorepo | Turborepo + pnpm workspaces |
| Frontend | Next.js 15 (App Router), React 19, TypeScript |
| UI | Tailwind CSS, shadcn/ui (Radix), Lucide, sonner |
| Canvas | Custom HTML5 Canvas |
It's a pnpm + Turborepo monorepo with three deployable services:
| Service | What it does |
|---|---|
drawboard-frontend |
Next.js 15 / React 19 — landing, auth, dashboard, and the canvas board (/canvas/[roomId]) |
http-backend |
Express REST API — auth (email + Google OAuth), rooms, access requests, chat history |
ws-backend |
ws WebSocket server — live draw / update / erase / sync / clear / chat messages |
Plus shared packages: @repo/db (Prisma + PostgreSQL), @repo/common (Zod schemas for shapes and auth payloads), @repo/ui, @repo/backend-common (JWT helpers). One command — pnpm start:unix — frees ports 3000/3001/8080 and boots all three services together. There's no token in the codebase you can't audit and no behavior you can't change.
How I Built It
The open-source AI is in the process as much as the product: I built DrawBoard entirely inside OpenCode, an open-source agent harness, running GLM, an open-weight model. No paid API key, no proprietary assistant in the loop — the same agent harness pattern anyone can clone from a public repo and run today, pointed at a model whose weights are published.
How that actually played out across the build:
- The canvas engine — a custom HTML5 Canvas layer, not a giant dependency. I went into it knowing the real-time sync protocol decisions matter more than the drawing code, and the community thread I leaned on here was @harshattray's "Frontend System Design: Designing a Collaborative Whiteboard", which walks from blank page to production architecture — I'd been priced by my own past attempts at hand-rolling this; reading someone else's take made it concrete.
-
The realtime layer — the agent and I settled on a plain
wsserver with explicit JSON message types (join_room,draw,update,erase,sync,clear,chat) rather than a framework. The tradeoff discussion borrowed from @kalevski's "Building Real-Time Apps in Node.js with Rivalis: WebSockets, Rooms, Actors, and a Binary Wire" — explicit message types keep the server auditable in an afternoon, which mattered because this whole codebase's selling point is that you can read it. -
Realtime architecture posture — @iammuhammadarslan's "Building Scalable Real-Time Applications with Node.js, Socket.io, and React" was a useful sanity-check on Socket.io vs raw
wsfor this scale; we chose the thinner dependency. - Working with the agent — the workflow that stuck: I asked it to read the code and verify its claims against the actual repo rather than repeat conventions from memory. That discipline bit already once: this week the agent found the README had been saved with broken encoding (mojibake diagrams + null bytes), documented a start script that didn't exist, and was missing an entire room access-request flow from the docs — rewrite it against the real schema (User → RoomAccess / AccessRequest → Chat in Prisma) instead of trusting my description of it.
Everything ships with a permissive license, a plain-language README, and an .env.example — so a reader can clone, set two variables, and have the full three-service stack running locally on Node 18 and Postgres.
Why Does Open Innovation Matter?
Three concrete reasons it made THIS build possible, not just a nicer flavor of it:
Zero marginal cost to iterate. An open-weight model cost me nothing per token. I could burn through dozens of agentic sessions — regenerate the tool-dock UI, redo the sync message schema, restructure the monorepo — with no pricing anxiety. A metered closed API quietly pushes you toward fewer attempts, and fewer attempts means a worse product. With GLM's open weights I never once thought "I shouldn't ask that again."
The process is inspectable, so the product is trustworthy. Because the harness is open source and the model is open-weight, I can see how the agent works, pin its behavior, and hold it to what it writes. When I tell readers "the codebase has no black box in it," I can say the same about the tooling that produced it. A closed API is a black box inside a black box.
The stack stays fully open, end to end. Next.js, React, Tailwind, shadcn/ui, Express,
ws, Prisma, PostgreSQL, Turborepo — every layer is something a 16-year-old in a small town with no cloud budget can clone and run. That's who open innovation is for: the person this challenge's sloth would want behind the keyboard. Nobody needs my permission to fork DrawBoard, self-host it behind their own firewall, and delete the parts they don't want.
My Agent Session
The full working session — from diagnosing the corrupted README, to challenging the agent's stale claims against the real Prisma schema and Express routes, to preparing this submission — is embedded below. It also shows the discipline I'd recommend to anyone vibe-building with agents: make it re-read the repo instead of quoting its memory.
The Lazy Payoff
Real numbers, no exaggeration:
- Ship time: this monorepo — a canvas engine, a REST API, a WebSocket sync server, auth with Google OAuth, room ACLs with approve/reject logic, chat, PNG/SVG export — went from "someday" idea running in my head to a deployed app with a live demo, inside one challenge window. Hand-rolling that used to translate into multiple abandoned weekends of mine.
-
Setup time: clone + two env vars +
pnpm start:unixand all three services are up with correct ports. Before this repo had a decent README, an agent literally diagnosing a corrupted README with null bytes was the debugging tax I was still paying this week — that friction is now zero for the next person. - Guest path: zero signup for a first draw. Share-link join with owner-approved access requests. If someone just wants to sketch with a friend for five minutes, the entire cost is opening a URL.
The sloth won this week, and it won honestly: the open agent did the work, and I stayed steady while it did it.
Top comments (0)