Designing for Handoff
Design Figma files that translate cleanly into code — naming conventions, file structure, autolayout rules, and communication patterns for developers and AI agents.
The gap between Figma and code is where projects lose momentum. This page covers what designers can do inside Figma to close it — for both human engineers and AI agents. They need the same things: named layers, token values, autolayout, and every important state shown.
Why handoffs break
| Failure mode | What happens | Consequence |
|---|---|---|
| Unnamed layers | Rectangle 47, Group 12 — agent generates div.Rectangle47 | Garbage component names, missed matches |
| Arbitrary values | A hex that differs from the design token by 1% | Designer goes "why doesn't it look right?" |
| Missing states | Only the happy path is shown at desktop width | Loading, empty, error, mobile all break in production |
| Broken autolayout | Frames with absolute-positioned children | Cannot translate to flexbox/grid — agent guesses and gets it wrong |
| No variant structure | Six separate button frames instead of one component with variants | Agent creates six separate components, no reuse |
| Lorem ipsum | Placeholder copy used throughout | Real content breaks layout; nobody caught the 3-line names that overflow |
Each of these is preventable by working inside Figma with the code translation in mind from the start.
Figma file structure
Figma file structure
Name pages after routes. This gives agents an immediate map from design to codebase.
Figma page name → App Router path
─────────────────────────────────────────────
Dashboard → app/dashboard/
Dashboard/Home → app/dashboard/page.tsx
Dashboard/Projects → app/dashboard/projects/page.tsx
Auth → app/auth/
Auth/Login → app/auth/login/page.tsx
Auth/SignUp → app/auth/signup/page.tsx
Settings → app/settings/page.tsxWithin a page, group frames into named sections that correspond to layout slots:
Dashboard page
├── Sidebar → layout sidebar slot
├── Header → layout header slot
├── Main/ProjectTable → page content
└── Main/QuickActions → page contentIf your codebase uses route groups like (dashboard), name your Figma pages the same way. The goal is that someone — human or agent — can look at the Figma file and know exactly where every screen lives in the repo.
Layer naming conventions
Every layer name should answer: what component is this in the codebase?
Component names
Use PascalCase matching your component naming convention:
| Layer name | Maps to |
|---|---|
Button/Primary/Large | <Button variant="primary" size="lg"> |
Card/ProjectSummary | <ProjectSummaryCard> |
Input/Email | <Input type="email"> |
Table/HeaderRow | Table header row component |
Badge/Status.Done | <Badge status="done"> |
Grouping with slashes
Forward slashes create collapsible groups in Figma's layer panel and encode the hierarchy:
Page/Dashboard
├── Sidebar/Nav/Logo
├── Sidebar/Nav/Link.Home
├── Sidebar/Nav/Link.Projects
├── Header/SearchInput
├── Header/UserMenu
├── Main/Toolbar
├── Main/Table.Header
└── Main/Table.RowDo not leave layers named Rectangle 47, Frame 12, or Component 1. Every unnamed layer is a missed opportunity for the agent to understand what it should build. Budget 5-10 minutes per page to clean up layer names before handoff.
Autolayout rules
Auto Layout in Figma translates almost 1:1 to CSS flexbox. Every frame should use Auto Layout unless there is a specific reason not to.
| Figma property | CSS equivalent |
|---|---|
| Direction (horizontal) | flex-direction: row |
| Direction (vertical) | flex-direction: column |
| Gap | gap |
| Padding (all sides) | padding |
| Horizontal padding | padding-inline |
| Vertical padding | padding-block |
| Alignment (top/left/center/right/bottom) | align-items + justify-content |
| Space between | justify-content: space-between |
| Hug contents | width: fit-content / height: fit-content |
| Fill container | width: 100% / height: 100% / flex: 1 |
| Wrap | flex-wrap: wrap |
What to avoid
- Absolute positioning — has no clean CSS flexbox equivalent. Use Auto Layout frames instead.
- Overlapping elements with manual x/y coordinates — translate to relative positioning or z-index with intent.
- Mixed-direction layouts without wrapping — if content needs to break into rows, use Wrap.
- Nested Auto Layout frames used as centering hacks — these produce unnecessary nesting in generated code. Use alignment properties instead.
Token-aware design
Design tokens are the single source of truth for colours, spacing, typography, and radii. When designers use tokens instead of raw values, the generated code references the same variable as the codebase. When they use raw values, agents inline hex codes and magic numbers.
Figma variables → CSS custom properties
Create Figma variables that match your CSS custom properties exactly:
Figma variable CSS custom property
─────────────────────────────────────────────
color/primary/500 --color-primary
color/neutral/100 --color-neutral-100
spacing/4 --spacing-4 (1rem)
spacing/8 --spacing-8 (2rem)
radius/md --radius-md
font/sans --font-sansRules for token usage
- Bind every colour fill to a Figma variable, never a raw hex
- Bind every spacing value (gap, padding, margin) to a spacing variable
- Use text variables for font family, size, weight, and line height
- If a value does not exist as a token, add the token — do not use a raw value
Tools like Tokens Studio, the Figma Variables API, or CI-driven token sync can keep Figma and code in sync bidirectionally. Start with a manual token audit: export your Figma variables, diff them against your globals.css, and align mismatches. See AI-Ready Design Systems for the schema that agents consume.
Component variants → code props
Figma component variants should map directly to React component props. The cleaner the mapping, the less the agent has to guess.
States as variants
Model every interaction state as a component variant, not as a separate component:
| State | Variant value | Becomes prop |
|---|---|---|
| Default | default | state="default" |
| Hover | hover | Shown in prototype |
| Focus | focus | :focus-visible styles |
| Active/pressed | active | :active styles |
| Disabled | disabled | disabled prop |
| Loading | loading | isLoading prop |
Sizes as a separate axis
Keep size variants on their own property axis so they compose with states:
Property 1: Size → sm | md | lg
Property 2: State → default | hover | focus | active | disabled | loadingThis maps to:
<Button size="sm" state="default">Save</Button>
<Button size="lg" disabled>Save</Button>Agents that see this variant structure generate a single component with props. Agents that see six disconnected button frames generate six separate components.
What agents and developers need
Before handing off a design file, verify that every screen includes:
States
Every screen must show more than the happy path. Include at minimum:
- Loading — skeleton or spinner for every data-dependent region
- Empty — what the user sees before data exists
- Error — API failure, validation error, or permission denied
- Success — confirmation after completing an action
- Edge cases — long names, zero results, expired sessions
Real copy
Use the actual text that will appear in the product. Lorem ipsum hides layout problems: names that are 3 lines long, button labels that overflow, headings that wrap at awkward breakpoints.
Breakpoint annotations
Note where the layout changes in frame names or descriptions:
Frame name: "Dashboard/Home [desktop: 1440]"
Frame name: "Dashboard/Home [tablet: 768]"
Frame name: "Dashboard/Home [mobile: 375]"Dev Mode annotations
Use Figma Dev Mode to annotate:
- Spacing values between elements
- Component names matching the codebase
- Token references for colours and typography
- Notes about responsive behaviour or interaction details
AI agents that have access to Figma (via MCP or plugins) can read Dev Mode annotations and use them to verify generated code against the design. The more information you encode as structured data rather than visual appearance, the more accurate the agent's output. See Agent Collaboration for prompt templates that reference Figma designs.
Design-to-code tools
Several tools now translate Figma designs directly into code. They are not replacements for design engineering — they are accelerators that handle the mechanical translation so you can focus on the decisions that matter.
Tool comparison
| Tool | Best for | Output | Limitations |
|---|---|---|---|
| Figma Dev Mode | Inspecting spacing, tokens, and component specs | Code snippets (CSS, Tailwind, SwiftUI) | Generates snippets, not complete components. Requires manual composition. |
| Figma-to-Code plugins (Anima, Locofy, Builder.io) | Rapid prototyping from high-fidelity mockups | React/Vue components with styles | Output quality varies with Figma file discipline. Named layers and autolayout are essential. |
| v0 / Bolt / Lovable | Generating full pages from prompts or screenshots | Complete React + Tailwind components | Design fidelity depends on prompt quality. Needs human review for tokens, states, and accessibility. |
| AI coding agents (Claude, Cursor, Copilot) | Implementing components from Figma screenshots or Dev Mode references | Full component files with logic | Best results when Figma file is well-structured (named layers, tokens, autolayout). See Agent Collaboration. |
When to use which approach
| Scenario | Recommended tool |
|---|---|
| Quick prototype from a Figma frame | Figma-to-Code plugin + manual cleanup |
| Production component from a spec | AI coding agent with explicit prompt (states, tokens, accessibility) |
| Checking spacing and token values | Figma Dev Mode |
| Design system component with variants | Write by hand — generated code rarely handles variant APIs cleanly |
| Full page with complex layout | AI agent with layout prompt + manual layout shell |
Design-to-code tools are only as good as the Figma file they consume. A file with unnamed layers, arbitrary hex values, and no autolayout will produce garbage regardless of the tool. Invest in file structure and naming conventions first — the tools become useful after.
Handoff checklist
Before handing off a Figma file to a developer or agent, confirm:
- Every layer is named meaningfully — no
Rectangle 47,Frame 12, orComponent 1 - Pages are named after routes or route groups
- All colours come from Figma variables matching CSS tokens
- All spacing (gap, padding) comes from spacing variables
- Every frame uses Auto Layout
- Interaction states (hover, focus, disabled, loading) exist as component variants
- Loading, empty, error, and edge-case states are shown for every screen
- Real copy is used in place of lorem ipsum
- Breakpoint-specific frames are annotated
- Interactive prototype is linked for complex flows
Related pages
- Product Designer First — Product thinking before interface work
- Design System — Token architecture and system structure
- AI-Ready Design Systems — Token schema for agent consumption
- Prototyping & Validation — Fidelity levels and testing
- Agent Collaboration — Prompt patterns for working with agents
Design Engineer Mindset
What it means to be a design engineer — bridging product design and engineering, owning the visual and functional quality of every component.
Stakeholder Communication
Present design decisions, give and receive critique, and translate between designers, developers, and clients — the soft skills that make design engineering work.