Building Figma Today
If you were building Figma (or Vizcom) from scratch in 2025, what would the optimal stack look like?
The Stack
┌─────────────────────────────────────────────────────────────┐
│ UI Layer │
│ TypeScript + React/Svelte │
│ (toolbars, panels, menus — not the canvas) │
└─────────────────────────┬───────────────────────────────────┘
│ wasm-bindgen
┌─────────────────────────▼───────────────────────────────────┐
│ Core Engine │
│ Rust → WASM │
│ • Document model (scene graph) │
│ • Undo/redo, history │
│ • Constraint solving │
│ • Export/import │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ Rendering Engine │
│ Vello (or custom) + wgpu │
│ • GPU compute-based 2D rendering │
│ • Tile-based for infinite canvas │
│ • Partial refresh for performance │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ Graphics API │
│ WebGPU │
│ (WebGL2 fallback via wgpu compatibility) │
└─────────────────────────────────────────────────────────────┘
Key Architectural Decisions
1. Rust + WASM for Core
Not JavaScript. The document model and rendering pipeline need:
- Predictable memory layout
- No GC pauses
- Near-native performance
Rust provides this with modern tooling. C++ (Figma’s choice in 2015) works too but Rust’s WASM ecosystem is now superior.
2. WebGPU First
WebGL is frozen. WebGPU offers:
- Compute shaders (for effects, physics)
- 2-3x performance gains
- Multi-threaded command preparation
- Better mobile power efficiency
Target WebGPU with WebGL2 fallback via wgpu’s compatibility layer.
3. Vello for Rendering
Don’t build a renderer from scratch. Vello:
- GPU compute-centric (not CPU-bound like Skia)
- 177 fps on 30k-element scenes
- Rust-native, WASM-ready
- Active development by Linebender
For simpler needs, Lyon handles path tessellation.
4. Loro for Collaboration
If you need real-time multiplayer:
- High-performance CRDT in Rust
- Canvas-optimized (lists, trees, undo)
- Works offline
- JS bindings via WASM
For simpler server-authoritative model (like Figma), roll your own with WebSocket + operational transform.
5. Tile-Based Infinite Canvas
Essential for performance:
- Only render visible tiles
- Cache tiles, invalidate on change
- Enable efficient zoom/pan
- Lazy-load document portions
For AI-Enhanced Tools (Vizcom-style)
Add these layers:
┌─────────────────────────────────────────────────────────────┐
│ AI Services │
│ • Image generation (Stable Diffusion, custom models) │
│ • Sketch-to-render inference │
│ • Material/lighting estimation │
└─────────────────────────┬───────────────────────────────────┘
│ API
┌─────────────────────────▼───────────────────────────────────┐
│ Cloud Backend │
│ • GPU inference (A100/H100) │
│ • Model serving (TensorRT, vLLM) │
│ • Caching layer (Redis) │
└─────────────────────────────────────────────────────────────┘
AI runs server-side (GPU too expensive for browser). Client sends sketches/prompts, receives rendered results.
Vizcom specifically uses:
- Custom diffusion models trained on industrial design
- Real-time material/lighting adjustment
- USDZ export for AR preview
Performance Targets
| Metric | Target |
|---|---|
| Initial load | <3s |
| First paint | <500ms |
| 60fps pan/zoom | 10k objects |
| Keystroke latency | <16ms |
| Collaboration RTT | <100ms |
Figma’s Rendering Internals
Figma recently replaced their legacy renderer with TinyGPU — a modern, minimal rendering backend. This laid the groundwork for WebGPU migration and performance optimization.
Two Renderer Architecture
Figma maintains two parallel renderers:
- WebGL renderer — Legacy, broad compatibility
- WebGPU renderer — Modern, performance-focused
CPU-side code is shared (C++ compiled to WASM), only the GPU interface differs.
TinyGPU Approach
The name “TinyGPU” reflects the philosophy:
- Minimal abstraction — Direct GPU control
- Small codebase — Easier to optimize
- Platform-agnostic — Same code targets WebGL/WebGPU
This is similar to Zed’s Blade renderer — a thin layer over native APIs.
Tile-Based Rendering (Like Vello)
Figma uses tile-based rendering:
- Canvas divided into tiles (likely 256×256 or similar)
- Only dirty tiles re-rendered
- Tiles cached in GPU memory
- Enables efficient pan/zoom
Key insight: Most frames only touch a few tiles.
What Figma Does That’s Hard
- Font rendering: Custom text layout engine. Use cosmic-text or skrifa.
- Constraint systems: Auto-layout, smart guides. Requires constraint solver (Cassowary or custom).
- Plugin API: Sandboxed JS runtime (like QuickJS). Complex security model.
- Export fidelity: PDF/SVG export matching screen exactly.
- Sub-pixel positioning: Snapping to pixel grid while preserving relationships.
- Boolean operations: Path union/intersection. Use Clipper2 or custom.
Bill of Materials
| Component | Library |
|---|---|
| Core language | Rust |
| WASM bindings | wasm-bindgen, wasm-pack |
| GPU API | wgpu (WebGPU + WebGL2) |
| 2D rendering | Vello |
| Path tessellation | Lyon |
| Text layout | cosmic-text |
| Font parsing | skrifa |
| Collaboration | Loro |
| UI framework | React or Svelte |
| Build | Vite + wasm-pack |
Start Small
Don’t build Figma. Build:
- Infinite canvas with pan/zoom
- Basic shapes (rect, ellipse, path)
- Selection and transform handles
- Undo/redo
- Export to PNG
Then iterate.
Related: webgpu vs webgl, rust wasm graphics, crdt real time collab, vello gpu vector graphics, webgpu future roadmap, gpui zed renderer