The Pragmatic Engineer
The Pragmatic Engineer
Building Figma Slides with Noah Finer and Jonathan Kaufman
0:00
Current time: 0:00 / Total time: -58:23
-58:23

Building Figma Slides with Noah Finer and Jonathan Kaufman

Figma engineers Jonathan Kaufman and Noah Finer share how they built Figma Slides from a hackathon project into a polished product, covering key engineering decisions, challenges, and practices.

Stream the Latest Episode

Listen and watch now on YouTube, Spotify and Apple. See the episode transcript at the top of this page, and a summary at the bottom.

Brought to You By

  • Graphite — The AI developer productivity platform.

  • Sonar — Code quality and code security for ALL code.

  • Chronosphere — The observability platform built for control.

In This Episode

How do you take a new product idea, and turn it into a successful product? Figma Slides started as a hackathon project a year and a half ago – and today it’s a full-on product, with more than 4.5M slide decks created by users. I’m joined by two founding engineers on this project: Jonathan Kaufman and Noah Finer.

In our chat, Jonathan and Noah pull back the curtain on what it took to build Figma Slides. They share engineering challenges faced, interesting engineering practices utilized, and what it's like working on a product used by millions of designers worldwide.

We talk about:

  • An overview of Figma Slides

  • Tech stack

  • Why the engineering team built grid view before single slide view

  • How all Figma files look the same across browsers

  • The "vibe testing" approach

  • How beta testing helped experiment more

  • The “all flags on”, “all flags off” testing approach

  • Engineering Crits

  • And much more!

Takeaways

My biggest takeaways from this conversation:

1. Figma’s web app uses a surprising amount of C++ code. It’s rare for web engineers to need to use C++ — but Figma is an exception, as the design tool built their own rendering engine. This means that frontend engineers need to get into the opinionated C++ codebase to make changes — though rewriting some parts of the code to TypeScript is currently on the way.

2. The “EngCrit” process is an interesting — and unique! — one. Figma’s engineering reviews/discussions are called EngCrit. An engineer presents their plan or idea in a FigJam board, and other engineers join in to give their feedback. This process has parallels with the RFC or design doc process — but it feels a lot more lightweight. Plus, it dogfoods Figma’s own products!

3. Some of the most straightforward UI parts are the most involved ones. It was interesting to learn that one of the most complicated pieces of the web app was the Single Slide View. This seemingly simple interface:

The “Single Slide View.” How hard could it be to build this seemingly simple UI?

The reason for the complexity was how this view is actually a zoomed in version of the grid view — this one:

The “Grid View.” The Single Slide View zooms into this visual, and hides everything else but the single slide

There are several reasons that the team decided to do this “zoomed in trick:” one of them is that when multiple people are editing a slide, zooming in means that the cursors for these other users show up both on the slide view and on the grid view.

This detail is a good reminder that a simple UI can hide a complex implementation.

The Pragmatic Engineer deepdives relevant for this episode

Timestamps

(00:00) Intro

(01:45) An overview of Figma Slides and the first steps in building it

(06:41) Why Figma built grid view before single slide view

(10:00) The next steps of building UI after grid view

(12:10) The team structure and size of the Figma Slides team

(14:14) The tech stack behind Figma Slides

(15:31) How Figma uses C++ with bindings

(17:43) The Chrome debugging extension used for C++ and WebAssembly

(21:02) An example of how Noah used the debugging tool

(22:18) Challenges in building Figma Slides

(23:15) An explanation of multiplayer cursors

(26:15) Figma’s philosophy of building interconnected products—and the code behind them

(28:22) An example of a different mouse behavior in Figma

(33:00) Technical challenges in developing single slide view

(35:10) Challenges faced in single-slide view while maintaining multiplayer compatibility

(40:00) The types of testing used on Figma Slides

(43:42) Figma’s zero bug policy

(45:30) The release process, and how engineering uses feature flags

(48:40) How Figma tests Slides with feature flags enabled and then disabled

(51:35) An explanation of eng crits at Figma

(54:53) Rapid fire round

A summary of the conversation

Initial development

  • The initial development took about 6 months, starting at a hackathon in late 2023 and the beta launch in April 2024. The public launch happened a week ago, on 19 March.

  • Phasing of the project

    • “Slide grid:” the first concept built on a hack week

    • The initial development was about getting the two-way navigation right between the grid view and the single slide view.

    • Single slide view construction happened later, around 6 months into the project.

    • Single slide view operates by zooming into the infinite canvas and hiding elements, maintaining the 2D space. Clever!

  • User researcher part of the team: this was surprising to hear! The researcher helped a lot with getting the direction of the project right – building something designers would find intuitive to use

Tech stack and tools

  • Figma's core editors use a C++ codebase and custom renderer outputting to a <canvas> element via WebGL or WebGPU.

  • UI elements outside the canvas use TypeScript and React.

  • A "bindings layer" enables communication between the C++ codebase and the web UI.

  • The C++ codebase

    • Some engineers join with C++ experience; others learn on the job.

    • Both Jon and Noah learned C++ on the job, for the most part!

    • The C++ codebase has a learning curve, similar to game engine development.

  • Rewriting some C++ to Typescript

    • Figma is rewriting parts of the C++ codebase into TypeScript, using the bindings layer.

    • Interactive elements like plus buttons use TypeScript to interact with the C++ canvas.

  • Tooling for debugging

    • A Chrome extension called DWARF debugging is a powerful tool the team uses

    • This extension debugs C++ code within Chrome Inspector, even as WebAssembly, similar to JavaScript source maps.

    • Breakpoints can be set in TypeScript/React and C++ WebAssembly for debugging interactions.

    • This tooling helps find intricate bugs between the UI and the core editor.

    • Previously, C++ debugging involved running a special build in Xcode.

    • Figma has an internal "web bisect" tool using commit previews to identify bug-introducing commits. A very helpful tool!

Engineering practices

  • Testing: the team does a lot of this.

    • They run all unit and interaction tests with flags off and then on. Another clever approach

    • This practice helps prevent regressions caused by specific feature flags.

  • Feature flags: extensively used. The product has more than 2,000 of these.

    • Developers have an internal panel to manage feature flags locally and in staging.

  • Staging: a dedicated staging environment used for testing. Features in this environment are enabled via flags. Staging is used to get early product feedback

  • Alpha launch: this was done for Slides by involving select customers

  • Eng Crits: asynchronous feedback via sticky notes in FigJam, followed by discussion.

  • Zero bug policy

    • Figma has a "zero bug policy" for new developments, prioritising fixes after launch

    • The on-call process triages feedback, and addresses reported issues promptly.

  • Beta phase: this 11-month long period prioritized critical bugs affecting core experience before the broader launch.

Engineering challenges

  • Single slide view implementation as viewport manipulation presented unique challenges.

  • This approach allows existing multiplayer cursor functionality in both views.

  • Multiplayer uses a server-side Rust service for edit propagation and conflict resolution via WebSockets.

  • Ensuring "interop" between Figma products

    • Ensuring products like Design, FigJam, and Slides work nicely with one another

    • Supporting interop means new node types must function across editors.

    • What makes it easier is how the underlying C++ codebase is largely shared across editors.

    • Differences in interactions use "mouse behaviors", editor-specific implementations for mouse actions. The mouse behavior concept comes from game engine architectures.

  • Custom text rendering

    • Figma has custom text rendering for consistency across browsers and operating systems.

    • This means that in-house development is needed for features like spellcheck – something that comes for free for web apps using the DOM!

  • Managing a collapsed state in a single slide view without file persistence was a state management problem.

  • Reordering slides in single slide view with multiplayer

    • To do so: state mutations needed to be minimized

    • The solution used existing auto layout nodes, with each slide row as a node within a grid node

    • Reordering manipulates the "parent index" of row nodes, minimizing mutations

  • Testing complex multiplayer interactions

    • This was difficult to do! It’s hard to reproduce problematic multi-user scenarios

    • Extensive unit tests are put in-place for grid reconciliation. These cover past bug scenarios and assert expected mutations. (This is a clever way to ensure fewer regressions!)

Where to find Jonathan Kaufman:

• X: https://x.com/kauffecup

• LinkedIn: https://www.linkedin.com/in/jkaufman5/

• Website: https://www.jkaufman.io/

Where to find Noah Finer:

• X: https://x.com/finerflame

• LinkedIn: https://www.linkedin.com/in/noahfiner/

• Website: https://noahfiner.com/

Mentions during the episode:

• Figma: https://www.figma.com/

• Figma Slides: https://www.figma.com/slides/

• Config: https://config.figma.com/

• FigJam: https://www.figma.com/figjam/

• C++: https://en.wikipedia.org/wiki/C%2B%2B

• Typescript: https://www.typescriptlang.org/

• React: https://react.dev/

• Debug C/C++ WebAssembly: https://developer.chrome.com/docs/devtools/wasm

• Xcode: https://developer.apple.com/xcode/

• Multiplayer cursors: https://www.figma.com/community/file/1267761575266415196/multiplayer-cursors

• How Figma’s multiplayer technology works: https://www.figma.com/blog/how-figmas-multiplayer-technology-works/

• Design-first software engineering: Craft – with Balint Orosz: https://newsletter.pragmaticengineer.com/p/design-first-software-engineering

• Reconciliation: https://legacy.reactjs.org/docs/reconciliation.html

• Inside Figma’s Engineering Culture: https://newsletter.pragmaticengineer.com/p/inside-figmas-engineering-culture

• How we engineer feedback at Figma with eng crits: https://www.figma.com/blog/how-we-run-eng-crits-at-figma/

• Nextjs: https://nextjs.org/

• Hacker News: https://news.ycombinator.com/

• Refactoring UI: https://www.refactoringui.com/

• Tailwind: https://tailwindcss.com/

• Adam Wathan’s website: https://adamwathan.me/

• Steve Schoger’s website: https://www.steveschoger.com/

• Piranesi: https://www.amazon.com/Piranesi-Susanna-Clarke/dp/1635577802/

• Immune: A Journey into the Mysterious System That Keeps You Alive: https://www.amazon.com/Immune-Kurzgesagt-gorgeously-illustrated-immune/dp/1529360684

Production and marketing by Pen Name. For inquiries about sponsoring the podcast, email podcast@pragmaticengineer.com.

Discussion about this episode