The Problem
Every whiteboard app I tried wanted me to sign up, sync to the cloud, or load 2MB of JavaScript. I just wanted a blank canvas.
The Solution
MindNotes Pro — a drawing app with 3 production dependencies:
react, react-dom, zustand
That's it. No Redux. No styled-components. No axios. No lodash.
Architecture
The drawing engine lives in a single Canvas.tsx file (~600 lines). It uses the Canvas API directly — no drawing library. State is managed by 3 small Zustand stores:
-
useDrawingStore— strokes, shapes, tools, undo/redo, localStorage persistence -
useViewStore— zoom and pan -
useThemeStore— dark/light theme with system detection
Key Technical Decisions
1. Canvas API over SVG
Canvas gives us hardware-accelerated 2D drawing and pixel-perfect control. SVG would have been easier for hit testing, but Canvas handles thousands of strokes without DOM overhead.
2. Zustand over Redux
Zustand is under 1KB and needs no boilerplate. A single useDrawingStore holds all drawing state. Subscriptions trigger Canvas redraws.
3. No external CDN
Everything is bundled — fonts, icons, even the SVG noise texture for the paper background. This makes the app accessible from China without a VPN.
4. Warm parchment design
Instead of the typical cold blue/gray UI, I used a warm earth tone palette (#f5f0e8 background, #c47a5a accent) with SVG fractal noise for paper texture.
Features
- 6 brush types: pen, highlighter, pencil, calligraphy, dashed, glow
- 9 drawing tools: select, pen, eraser, pan, rectangle, circle, text, line, arrow
- 6 export formats: PNG, JPG, PDF, SVG, Word, JSON
- Auto-save to localStorage
- 50-step undo/redo
- Zoom & minimap navigation
- Dark mode with system detection
- Touch support for tablets and phones
Results
| Metric | Value |
|---|---|
| Bundle size | ~160KB gzipped |
| Dependencies | 3 |
| External CDN calls | 0 |
| Build time | ~2 seconds |
Try It
Built with React 18, TypeScript 5, Vite 5, Zustand, Canvas API, and Tailwind CSS.
Top comments (0)