All posts

March 24, 2026

Why Designs Should Be Code

Figma has a private data model that doesn't map to how browsers render pages. Every design-to-code workflow built on top of it is working around that mismatch. Here's what the translation problem actually costs — and why code-native design is the structural fix.

Figma is a remarkable piece of software. It's fast, it's collaborative, it handles complex design files well, and it has become the default tool for most product design teams. The design industry consolidated around it for good reasons.

It also has a fundamental architecture problem that has generated an entire ecosystem of workarounds, plugins, and tooling — not because the people building those tools are filling gaps out of passion for adjacent products, but because the gap is load-bearing. The design artefact and the production code are in different languages, and the translation between them is never clean.

Understanding why requires looking at what Figma actually is, at the data model level.


The Figma data model is not the web's data model

When you open a Figma file, you're working with a proprietary tree of nodes. Frames contain groups contain components contain vectors. Constraints define how elements resize. Auto Layout — Figma's layout engine — uses a proprietary flex model. Styles, variables, and component properties are Figma concepts: they live in the Figma file, they're stored in Figma's format, and they're accessed through Figma's API.

None of this maps directly to how a browser renders a page.

The web's layout model is CSS: display: flex, grid-template-columns, gap, padding, position. Figma's Auto Layout and the web's Flexbox share a conceptual lineage — both are inspired by CSS Flexbox — but they're not the same. Auto Layout has "hug contents" and "fill container" modes; CSS has width: fit-content and flex: 1. They produce similar layouts. They're not the same language. A direct translation requires interpretation.

Component properties in Figma — variants, instance swaps, boolean toggles — are also different from component props in React or any other component framework. A Figma component with a "variant=destructive" property is not the same as a React component with a variant="destructive" prop, even though they conceptually represent the same thing. The mapping has to be defined manually, or inferred by a tool that may or may not get it right.

Design tokens — named values for colours, type scales, spacing — exist in Figma as styles and variables. They also exist in codebases as CSS custom properties, Tailwind config values, or theme files. These two token systems are separate, and keeping them in sync requires either a process, a tool, or — most commonly — neither, so they drift.


The plugin ecosystem as evidence of the gap

The Figma plugin ecosystem has over 700 plugins. A significant fraction of them exist specifically to bridge the design-to-code gap in some form:

  • Plugins that export CSS from Figma frames
  • Plugins that generate React components from selected elements
  • Plugins that sync design tokens to a code repository
  • Plugins that read Storybook stories and display them in Figma
  • Plugins that import live components from code into the Figma canvas
  • Plugins that annotate spacing and sizing for developer handoff
  • Plugins that flag when a design uses a value not in the token system
  • Plugins that generate Tailwind classes from Figma properties

The scale is significant. Anima — one of the most-installed Figma design-to-code plugins — had reached 1.5 million installs before the MCP era, representing a massive install base for a tool whose sole purpose is to automate part of the translation from Figma's format to deployable frontend code. The existence of millions of installations across dozens of competing translation tools is not evidence of a healthy, extensible platform. It's evidence that the core architecture creates so many translation problems that a cottage industry has formed around plugging them.

This is not Figma's fault in any meaningful sense. Figma is a design tool, not a code generator. Its data model is optimised for visual editing, collaboration, and design exploration — not for mapping to production codebases. The mismatch is architectural, not a bug.

The problem is the assumption that Figma is the right primary artefact for a design-to-code workflow. When the design artefact lives in a system that doesn't share a language with the build artefact, translation is always required. And translation is always lossy, expensive, and a source of drift.


What handoff actually costs

"Design handoff" is the industry term for the process of getting design decisions from the design tool into the engineering team's heads and hands. It has become its own discipline, with dedicated roles (design technologists, design engineers), dedicated tooling (Zeplin, Avocode, Storybook, a dozen others), and dedicated workflows (redlines, inspection mode, design QA).

The existence of this entire discipline is the translation cost made organisational. Someone has to bridge the gap between the Figma file and the codebase. That person or process is doing work that wouldn't exist if the two artefacts were in the same language.

The numbers behind the cost are measurable. Research on product team misalignment found that design errors and miscommunication at the handoff boundary account for 68% of rework costs in product development. A 2025 Boston Consulting Group report found that companies with formal handoff practices — shared component libraries, explicit design QA, documented handoff protocols — reduced rework cycles by an average of 47% compared to teams without them. The gap between the organisations that invest in handoff and those that don't is nearly half their engineering rework budget.

The work is not trivial. A frontend engineer implementing a design from Figma is making dozens of interpretation decisions: what the right component to use is, how this spacing should be expressed in the token system, whether this visual treatment is a new component or a variant of an existing one, how the hover state should be implemented, what the keyboard behaviour should be. Figma doesn't tell you any of this. The engineer infers it, correctly some of the time and incorrectly some of the time, and the gaps between correct and incorrect inference are what design QA exists to catch.

Tooling like Figma's Dev Mode improves this — it surfaces CSS values, component names, design token references, and other structured information that makes inference more accurate. But it doesn't eliminate the translation; it makes it more legible. An engineer using Dev Mode is still translating from Figma's representation to code. They're doing it more accurately, but they're still doing it.


What "design as code" actually means

If design artefacts were code — component-level, styled, structured in the same language as the production frontend — the translation problem disappears.

A design in code is already an implementation. The "handoff" is a merge. The "inspection" is reading the file. The "design tokens" are CSS custom properties. The "component variants" are React props. The gap between design intent and implementation is closed by construction, because both are expressed in the same representation.

This isn't a hypothetical. It's what component libraries, design systems, and tools like Storybook are trying to create: a canonical set of components that design and engineering share, in code, so that building from them doesn't require translation. The challenge is that building a component library takes significant upfront investment, and most teams don't have it — so they design in Figma and build from the design, and the translation cost is paid on every feature.

Code-native design tools — tools that generate actual component-level UI code, styled to a design system, from a product specification — skip the translation layer entirely. The design and the build artefact are the same thing, or adjacent enough that the gap is minimal. When the designer changes a flow, the code that implements the flow changes. There's no separate synchronisation step, no separate handoff artefact, no inference cost.


The drift problem

There's a second cost to the Figma-as-source-of-truth model beyond the initial handoff: maintenance.

Products change. Flows get redesigned. New features get added. The design file and the codebase both change over time, and they change on different schedules, maintained by different people using different tools. The result is that the design file and the production codebase diverge — usually slowly, then suddenly.

A year into a product, the Figma file represents a combination of screens that are accurate, screens that are outdated, screens that were designed but never built, and features that were built but never designed. It's no longer a reliable source of truth for what the product looks like. It's a historical record of design intentions, some of which made it to production and some of which didn't.

This is the normal state of design artefacts in the Figma model. It's accepted as inevitable.

In a code-native model, there's one source of truth: the code. The design lives in the codebase. When the product changes, the design changes in the same place, at the same time. The artefact stays current because it is the production artefact, not a separate representation of it.


How Mowgli approaches this

Mowgli generates designs that are structured for export to code — component-quality screens built on a consistent design system, with the visual language, spacing, and component structure that translates into a coherent implementation.

The spec that drives the generation stays in sync with the design. When you iterate on a flow, the spec updates. When you export or hand off to a coding agent, what they're working from is the current design in its current state — not a snapshot from three months ago, not a partially updated file with some screens accurate and some stale.

The full export path — from Mowgli's canvas to a working codebase, via direct export or a coding agent — is designed to minimise translation: the design is already expressed at the component and layout level, in a structure that maps to how production frontends are built.

This doesn't eliminate all handoff complexity. But it removes the deepest layer of the problem: the architectural mismatch between a proprietary design format and the web's layout model. When the design was always destined to be code, generating it as code from the start is the faster, more accurate, and more maintainable path.

We explore the case for spec-driven building in Why Spec-Driven Development Is the Future of AI-Assisted Building. For a deep dive into how Mowgli's Figma import pipeline works — and the origin story behind it — see The Figma Import That Actually Works.


Sources