Figma runs an entire design tool — vector editing, real-time multiplayer cursors, an infinite zoomable canvas — inside a browser tab, at 60 frames per second, without a native app. The reason it can do that isn't a clever CSS trick. It's that Figma's core renderer isn't really a web app at all: it's C++ code, compiled to WebAssembly, that draws directly to the GPU and treats the browser as little more than a window to paint into.
Why Figma's Engineers Ruled Out HTML, SVG, and the 2D Canvas API
Think of a browser tab like a kitchen you're renting instead of one you built yourself. HTML, SVG, and the 2D Canvas API are the appliances that come with the kitchen — and Figma's co-founder Evan Wallace explained, in the company's first engineering post, why none of them were good enough for a professional design tool.
The problem wasn't any single missing feature. HTML and SVG carry DOM overhead and are often much slower than the 2D canvas API due to DOM access, and browsers give no guarantee of GPU acceleration for them. Masking, blurring, and blend-mode support varied wildly between browsers and often wasn't anti-aliased or was too low-resolution on high-DPI screens. The 2D Canvas API had a more fundamental issue: it's an "immediate mode" API, meaning every frame has to re-upload all of a shape's geometry to the graphics card again, which is wasteful and becomes a bottleneck at scale. On top of that, Figma wanted effects like angular gradients that none of the three could render at all.
So Figma's team didn't pick between HTML, SVG, and Canvas — they rejected all three and built a fourth option from scratch, on top of WebGL, with its own compositor and text layout engine baked in.
Compiling C++ to WebAssembly Removes JavaScript's Garbage Collector From the Frame Budget
Here's the part that actually explains the "60 FPS" claim, and it's simpler than it sounds. In a normal JavaScript app, the browser's garbage collector periodically pauses execution to clean up memory you're no longer using. Most of the time that pause is invisible. But if it happens to land in the middle of a frame, you get a stutter — and a design tool with thousands of on-screen shapes creates and discards a lot of memory every time you drag something.
Figma's fix is to sidestep the garbage collector entirely for anything performance-critical. The editor is written in C++ and cross-compiled using Emscripten, and the compiler fully controls memory layout, using compact 32-bit floats or even single bytes instead of JavaScript's 64-bit doubles, which matters for an app handling large amounts of data. Critically, the compiled C++ objects are just reserved ranges inside one pre-allocated typed array, so the JavaScript garbage collector is never involved in managing them — which is what makes it much easier to hit 60fps by avoiding GC pauses in the first place.
A useful mental model: imagine a parking garage where every car gets a numbered spot assigned in advance, instead of circling for whatever's free. Nobody has to stop and search — and nobody has to periodically tow abandoned cars mid-shift to make room. That's the tradeoff C++ buys Figma: predictability, at the cost of the engineer having to manage memory correctly by hand instead of leaning on automatic collection. It's a real cost — manual memory management is exactly the class of bug that has pushed other systems languages toward compiler-enforced guarantees, including a language-level approach to solving the same memory-safety problem C++ leaves to engineers.
The 2018 Renderer Rewrite That Figma Says Made It Three Times Faster
Figma didn't arrive at this architecture in one step. The 2015 launch shipped on asm.js, the JavaScript-subset predecessor to WebAssembly proper, because WebAssembly was still an in-progress effort at the time to implement a binary format for asm.js code, aimed at drastically reducing parse time, with all major browser vendors already on board. Once WebAssembly matured, Figma moved the engine onto it — and in 2024's retrospective on its performance-testing practices, the company disclosed a specific result from that transition: in 2018, restructuring the document renderer and ironing out WebAssembly bugs made Figma three times faster.
Figma has published the multiplier for that 2018 rewrite but not the underlying millisecond benchmarks, so the chart below represents it as a relative index — three units of time before the rewrite against one unit after — rather than claiming exact measured numbers Figma hasn't disclosed.
WebGPU and Dawn: Splitting the Same C++ Renderer Between Browser and Server
Ten years after the WebGL bet, Figma extended the same architecture rather than replacing it. In September 2025, the company shipped WebGPU support alongside its existing WebGL path, and the underlying trick is what makes it worth understanding: it's the same C++ source, compiled twice. Figma's renderer is written in C++, compiled to WebAssembly using Emscripten for the browser, and separately compiled into a native x64/arm64 application used for server-side rendering, testing, and debugging. To keep both builds working through the same graphics calls, Figma incorporated Dawn, the WebGPU implementation used inside the Chromium browser, into its own build, so both the Wasm and native versions of the app translate WebGPU calls through the same underlying library.
WebGPU itself wasn't a drop-in speed boost — the team notes that simply switching from WebGL to WebGPU wasn't guaranteed to help, and implemented carelessly could have made performance worse, particularly around how each API batches data sent to the GPU. What WebGPU does unlock, once implemented carefully, is compute shaders that move work off the CPU and onto the GPU's parallel pipeline — useful for effects like blur that used to compete with everything else for CPU time. This is the same broader pattern showing up across the web-performance beat right now: teams re-drawing the line between "compiled once" and "runs everywhere," which is also visible in how compiler and runtime choices reshape build performance elsewhere in the web stack.
None of this is a one-time trick a team ships once and forgets. Every layer — the memory model, the compile targets, the graphics API — is a decision Figma has revisited as browsers evolved: asm.js gave way to WebAssembly, WebGL now runs alongside WebGPU, and the fallback logic between them exists precisely because "GPU-accelerated in the browser" is still a moving target across devices and drivers. The architecture holds up not because any single choice was permanent, but because the boundary Figma drew a decade ago — keep the renderer's logic in compiled, GC-free code, and let the browser handle only what it's actually good at — turned out to be the right place to put it.





Comments (0)
Please sign in to join the discussion.
No comments yet.
Be the first to share your perspective on this topic.