Loading...
Loading...
Staff · 60 min
Also asked as: Figma, Miro, Excalidraw, tldraw, Canva, FigJam.
Read it once, then start the timer and work without scrolling.
Design a Figma-style infinite canvas design tool where users manipulate thousands of vector objects with pan, zoom, and multi-user editing.
Everything below is a model answer. You will get far more out of this drill by attempting it cold first — set the timer, talk through it out loud, and only then compare.
A 60-minute phase plan you can practise against a clock.
Interactive · Drill rehearsal timer
7:00
Time remaining in Clarify and scope.
What you should establish before drawing a single box.
Architecture, data, interfaces, and optimisations — the RADIO body.
The half of the answer most candidates skip entirely.
Naming how the system breaks, and what the user sees when it does, is the cheapest way to signal production experience. Work through these before the interviewer has to ask.
The interviewer will challenge you. Rehearse the concession, not just the defence.
Interviewer
Figma is WebGL and WASM. Starting with Canvas 2D means you are guaranteeing yourself a rewrite in a year.
Model response
You may well be right about the endpoint, and I would not claim Canvas 2D scales to Figma's ceiling — at hundreds of thousands of vector objects with real-time effects, WebGL is not optional. What I am buying with Canvas 2D is text. Text layout and rasterization is the single hardest part of this system, the 2D context gives it to me correctly for free, and reimplementing kerning, shaping, and subpixel rendering on the GPU is a multi-quarter project on its own. So my sequencing is: ship Canvas 2D with tiling and LOD, which comfortably handles tens of thousands of objects, and keep the renderer behind an interface so the swap does not touch the scene graph, the CRDT, or the tools. The condition where I would go WebGL immediately is if the requirement named a six-figure object count or GPU-dependent effects up front — then the text problem has to be solved either way and delaying only wastes the Canvas work.
Interviewer
A CRDT for a tree is notoriously hard. Concurrent moves create cycles and orphans. Why not just use a server-authoritative model with optimistic updates, which is far simpler to reason about?
Model response
The tree CRDT complexity is real and you have named the exact failure — concurrent reparenting is the case that breaks naive implementations, and it needs an explicit cycle-detection rule rather than falling out of the algebra for free. Server-authoritative with optimistic local application is a legitimate design and it makes the conflict story much easier to explain. The reason I still lean CRDT is offline and latency: server-authoritative means a rejected operation gets rolled back under the user's cursor, and in a direct-manipulation tool a shape snapping back mid-drag is a severe experience failure. It also means no meaningful offline editing. If the requirements said always-online and no offline mode, and especially if there were already a team owning the authoritative service, I would take server-authoritative and spend the saved complexity budget on the renderer, which is where the user-visible risk actually lives.
Interviewer
You have a spatial index, a tile cache, LOD, a worker, two canvas layers, and a command layer. This is enormous. How does a small team ship any of it?
Model response
It is a lot, and if I presented it as a v1 scope I would deserve the pushback. The honest ordering by return on effort is: scene graph and command layer first, because everything else assumes them and they are cheap; then the spatial index, which is a few hundred lines and is the difference between a thousand objects and fifty thousand; then the overlay layer split, which is nearly free and removes most interaction jank. Tiling, LOD, and the worker are all optimizations I would defer until a profile demands them, and I would say so rather than building them speculatively. The two things I would not defer are the command layer and the renderer interface, because both are structural — retrofitting a command layer under an editor that mutates nodes directly means touching every tool, and that is the kind of change that never gets prioritized.
Interviewer
Per-user undo sounds clean but it produces confusing behavior. If I undo my move and someone has since deleted the object, what am I even undoing? Users will say the tool is broken.
Model response
They will, and there is no formulation of multiplayer undo that is never surprising — this is a genuine usability cliff, not just an implementation detail. What I would commit to is that undo never surprises you about your own work and never silently reverts someone else's. Concretely: undo inverts your command against current state, so undoing a move on a still-present object does exactly what you expect; if the target was deleted, the undo is a no-op with a brief toast explaining why, rather than resurrecting an object someone deliberately removed. The alternative — a global stack where your undo reverts a colleague's edit — is far worse, because it breaks the mental model that undo is personal. I would also treat this as a design partnership rather than an engineering decision alone, and I would want it in usability testing early, since which surprise users tolerate is an empirical question and not one I can settle at a whiteboard.
Specific signals an interviewer is listening for on this prompt.
Turn one attempt into retained skill.