← /research

Building Figma Today

Processing · Literature Review Created Jan 4, 2025
Project: web-graphics-research
graphicsarchitecturesynthesis

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

MetricTarget
Initial load<3s
First paint<500ms
60fps pan/zoom10k 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:

  1. WebGL renderer — Legacy, broad compatibility
  2. 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:

  1. Canvas divided into tiles (likely 256×256 or similar)
  2. Only dirty tiles re-rendered
  3. Tiles cached in GPU memory
  4. Enables efficient pan/zoom

Key insight: Most frames only touch a few tiles.

What Figma Does That’s Hard

  1. Font rendering: Custom text layout engine. Use cosmic-text or skrifa.
  2. Constraint systems: Auto-layout, smart guides. Requires constraint solver (Cassowary or custom).
  3. Plugin API: Sandboxed JS runtime (like QuickJS). Complex security model.
  4. Export fidelity: PDF/SVG export matching screen exactly.
  5. Sub-pixel positioning: Snapping to pixel grid while preserving relationships.
  6. Boolean operations: Path union/intersection. Use Clipper2 or custom.

Bill of Materials

ComponentLibrary
Core languageRust
WASM bindingswasm-bindgen, wasm-pack
GPU APIwgpu (WebGPU + WebGL2)
2D renderingVello
Path tessellationLyon
Text layoutcosmic-text
Font parsingskrifa
CollaborationLoro
UI frameworkReact or Svelte
BuildVite + wasm-pack

Start Small

Don’t build Figma. Build:

  1. Infinite canvas with pan/zoom
  2. Basic shapes (rect, ellipse, path)
  3. Selection and transform handles
  4. Undo/redo
  5. 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