The Developer Handoff: A Checklist for Creating Zero-Ambiguity Specs in Figma
Here's a conversation that happens in every design-to-dev handoff:
Developer: "Hey, what's the padding on this button?"
Designer: "It's in the Figma file."
Developer: "I see 16px on the left, but what about mobile?"
Designer: "Oh, mobile should be 12px."
Developer: "That's not in the spec. What about the hover state?"
Designer: "It's... let me check. I think I designed it but didn't update the components."
Developer: "And what happens when the text wraps to two lines?"
Designer: "Good question. Let me think about that."
Two days later:
The button is implemented. It mostly looks right. But:
- The padding is 16px on all breakpoints (dev didn't know about mobile)
- There's no hover state (dev guessed and used the wrong color)
- Long text breaks the layout (edge case wasn't designed)
- The button uses
#3B82F6 instead of the design token primary-600 (dev copied the hex code)
The result?
- Engineering time wasted on rework
- Design system inconsistency
- Designer frustration ("Why didn't they just follow the spec?")
- Developer frustration ("The spec was incomplete!")
The Problem: Ambiguity in Specs is a Design System Killer
Let's be honest: Incomplete specs are the #1 cause of design-to-dev friction.
Not poor communication. Not tool limitations. Not lack of collaboration.
Incomplete, ambiguous specifications.
Here's what happens when specs are ambiguous:
1. Developers Make Assumptions
When information is missing, developers fill in the gaps. They:
- Guess at spacing values
- Pick arbitrary colors from the palette
- Implement the "happy path" only (no error states)
- Use fixed dimensions instead of responsive layouts
Why? Because they're trying to unblock themselves. They have deadlines.
2. Implementation Drifts from Design
Small inconsistencies compound:
- One button uses 16px padding, another uses 12px
- Error states are inconsistent across forms
- Animations have different timing curves
- Mobile layouts don't match the responsive behavior in Figma
Over time, the codebase diverges from the design system.
3. Rework is Expensive
Finding and fixing inconsistencies after launch is 10x more expensive than getting it right the first time.
Because now you need to:
- Identify all instances of the inconsistent implementation
- Refactor the code
- Test for regressions
- Redeploy
All of this could have been avoided with better specs.
The Solution: A Zero-Ambiguity Handoff Checklist
A zero-ambiguity spec means:
- Developers have everything they need to implement the design
- No guessing, no assumptions, no follow-up questions
- Every state, every breakpoint, every interaction is documented
Here's the checklist I use to achieve this:
Part 1: The Pre-Handoff Checklist (In Figma)
Before you even think about handing off to dev, your Figma file must pass these quality checks.
✅ Step 1: All Components Must Be Componentized
The Rule:
Every repeated element must be a component. No detached instances. No local styles that aren't in your design system.
Why it matters:
- Ensures consistency
- Makes updates instant (change the component, all instances update)
- Developers can map Figma components 1:1 to code components
How to check:
- Select All (Cmd/Ctrl + A) in your design
- Look at the right panel for instances that show "Detached"
- Fix by reconnecting to the main component or creating a new component
Common violations:
| Violation | Fix |
|---|
| Detached button instance | Reconnect to main Button component |
| Text using local color instead of design token | Apply color style from design system |
| Icon imported as PNG instead of component | Replace with component from icon library |
| Card with manual padding instead of auto layout | Rebuild using Card component with proper spacing |
Example:
❌ Bad (Detached Instance):
Button instance (detached)
├─ Background: #3B82F6 (local color)
├─ Text: "Submit" (Roboto, manual styling)
└─ Padding: 12px 24px (manual values)
✅ Good (Proper Component):
Button/Primary/Medium
├─ Background: [primary-600] (design token)
├─ Text: "Submit" (Button/Medium style)
└─ Padding: [spacing-3] [spacing-6] (design tokens)
✅ Step 2: All States Must Be Defined
The Rule:
For every interactive element, design and document these states:
- Default (resting state)
- Hover (mouse over)
- Focus (keyboard navigation)
- Active (being clicked)
- Disabled (not interactive)
- Error (validation failure)
- Loading (async operation in progress)
- Empty (no data or content)
Why it matters:
If you don't design it, the developer will guess. And their guess won't match your design system.
How to implement in Figma:
Use component properties and variants to organize states:
Example: Button Component with States
Button Component
├─ Variant: State
│ ├─ Default
│ ├─ Hover
│ ├─ Focus
│ ├─ Active
│ ├─ Disabled
│ └─ Loading
├─ Variant: Size
│ ├─ Small
│ ├─ Medium
│ └─ Large
└─ Variant: Type
├─ Primary
├─ Secondary
└─ Tertiary
State-Specific Guidelines:
| State | What to Define |
|---|
| Hover | Background color, border color, text color, cursor style |
| Focus | Focus ring color, focus ring width, focus ring offset |
| Active | Pressed appearance (darker shade, inset shadow) |
| Disabled | Opacity (typically 0.5), cursor: not-allowed |
| Error | Border color (red-600), icon (error icon), helper text color |
| Loading | Spinner component, disabled appearance, loading text |
| Empty | Placeholder text, empty state illustration, CTA |
Common Mistakes:
❌ Only designing the default state
- Dev implements hover using arbitrary color
- Focus state is browser default (ugly blue outline)
- No disabled state (button remains clickable)
✅ Designing all interactive states
- Every state is explicitly defined
- Developer knows exactly what to implement
- Accessibility requirements are met (focus state for keyboard users)
✅ Step 3: Auto Layout Check
The Rule:
All frames should use Auto Layout. Avoid fixed pixel dimensions unless absolutely necessary (e.g., icons, avatars).
Why it matters:
- Ensures components are responsive
- Prevents layout breaking when content changes
- Makes it clear to developers how the component should reflow
How to check:
- Select a frame
- Look for the Auto Layout icon in the right panel
- If it's not enabled, right-click → "Add Auto Layout"
Auto Layout Best Practices:
| Property | Guideline |
|---|
| Direction | Use Horizontal or Vertical (match content flow) |
| Spacing | Use design tokens (e.g., spacing-4 = 16px) |
| Padding | Use design tokens (e.g., spacing-3 = 12px) |
| Alignment | Use Top/Center/Bottom, Left/Center/Right |
| Resizing | Set to "Hug" for content-based, "Fill" for container-based |
Example: Card Component with Auto Layout
Card (Auto Layout: Vertical, Spacing: 16px, Padding: 24px)
├─ Header (Auto Layout: Horizontal, Spacing: 12px)
│ ├─ Icon (Fixed: 24×24px)
│ └─ Title (Hug contents, Fill container width)
├─ Body Text (Hug contents, Fill container width)
└─ Actions (Auto Layout: Horizontal, Spacing: 8px)
├─ Cancel Button (Hug contents)
└─ Confirm Button (Hug contents)
What to avoid:
❌ Fixed pixel widths (e.g., Text frame = 320px wide)
- Breaks when content is longer
- Not responsive
✅ Fill container (Text frame = Fill)
- Adapts to container width
- Responsive by default
Part 2: The Specification Checklist (Documentation)
The Figma file shows what to build. The documentation explains how to build it.
✅ Step 4: Finalize All Microcopy
The Rule:
All user-facing text must be final, approved copy—not placeholder Lorem Ipsum.
Why it matters:
- Developers shouldn't have to guess at placeholder text, error messages, or tooltips
- Copy affects layout (long strings can break UI)
- Legal/compliance review may be required
What to document:
| Text Type | Example | Where to Document |
|---|
| Button labels | "Save Changes", "Cancel", "Delete Account" | Component properties |
| Placeholder text | "Enter your email address" | Input component |
| Helper text | "Must be at least 8 characters" | Form field |
| Error messages | "This email is already in use" | Error state variant |
| Empty states | "No results found. Try a different search term." | Empty state component |
| Tooltips | "Click to copy API key" | Tooltip component |
| Loading text | "Saving..." | Loading state variant |
How to document in Figma:
- Create a "Copy Specs" page in your Figma file
- List all microcopy in a table format
- Include context (where it appears, when it appears)
Example:
Copy Specifications
Form Validation Errors:
- Email (empty): "Email is required"
- Email (invalid): "Please enter a valid email address"
- Password (empty): "Password is required"
- Password (too short): "Password must be at least 8 characters"
- Password (no uppercase): "Password must include at least one uppercase letter"
✅ Step 5: Specify All Breakpoints
The Rule:
Document how the design behaves at different screen sizes.
Why it matters:
- Desktop design doesn't automatically translate to mobile
- Developers need to know when/how layout changes
Standard Breakpoints:
| Breakpoint | Width | Common Use |
|---|
| xs | < 640px | Mobile portrait |
| sm | 640px - 768px | Mobile landscape, small tablets |
| md | 768px - 1024px | Tablets |
| lg | 1024px - 1280px | Desktop |
| xl | 1280px+ | Large desktop |
What to specify:
- Layout changes (e.g., 3-column grid → 1-column stack)
- Spacing adjustments (e.g., 24px padding → 16px on mobile)
- Typography changes (e.g., 32px heading → 24px on mobile)
- Content visibility (e.g., hide secondary navigation on mobile)
How to document in Figma:
Create separate frames for each key breakpoint:
Homepage
├─ Desktop (1440px)
├─ Tablet (768px)
└─ Mobile (375px)
Example Breakpoint Spec:
Header Component
Desktop (lg: 1024px+):
- Height: 80px
- Logo: 48px width
- Navigation: Horizontal, right-aligned
- Padding: 24px
Mobile (sm: < 768px):
- Height: 64px
- Logo: 32px width
- Navigation: Hamburger menu (hidden by default)
- Padding: 16px
✅ Step 6: Document Animations and Micro-interactions
The Rule:
For any animation or transition, specify:
- Duration (e.g., 300ms)
- Easing (e.g., ease-in-out, cubic-bezier)
- Property (e.g., opacity, transform)
Why it matters:
- Animations feel random if timing/easing is inconsistent
- Developers default to browser defaults (which often feel wrong)
Common Animations to Specify:
| Interaction | Duration | Easing | Property |
|---|
| Button hover | 150ms | ease-out | background-color |
| Modal open | 300ms | ease-in-out | opacity, scale |
| Dropdown expand | 200ms | ease-out | height, opacity |
| Toast notification | 400ms in, 200ms out | ease-in-out | opacity, translateY |
| Loading spinner | 1000ms (loop) | linear | rotate |
How to document in Figma:
Use the Prototype panel to define interactions, then add notes in the component description.
Example:
Modal Component
Animation Specs:
- Open: 300ms ease-in-out
- Opacity: 0 → 1
- Scale: 0.95 → 1
- Background overlay: 0 → 0.5
- Close: 200ms ease-out
- Opacity: 1 → 0
- Scale: 1 → 0.95
Easing Reference:
| Easing | Use Case | CSS Value |
|---|
| Linear | Loading spinners, progress bars | linear |
| Ease | General animations (browser default) | ease |
| Ease-in | Elements leaving the screen | ease-in |
| Ease-out | Elements entering the screen | ease-out |
| Ease-in-out | Modals, overlays | ease-in-out |
| Custom | Bouncy animations, complex motion | cubic-bezier(0.68, -0.55, 0.265, 1.55) |
Part 3: The Delivery Checklist (The Meeting)
Don't just drop a Figma link and hope for the best. Proper handoff requires a structured walkthrough.
✅ Step 7: Hold a 15-Minute Walkthrough
The Rule:
Schedule a short sync with the dev team to walk through the most complex parts of the design.
Why it matters:
- Prevents misunderstandings
- Allows developers to ask questions upfront
- Builds shared understanding
Meeting Structure:
1. Context (2 minutes)
- What problem does this solve?
- What's the user flow?
- What are the key success metrics?
2. Component Overview (5 minutes)
- Walk through the component hierarchy
- Show how components are reused
- Point out variants and states
3. Edge Cases (5 minutes)
- What happens when text is really long?
- What happens when there's no data?
- What happens when the API call fails?
4. Q&A (3 minutes)
- "What questions do you have?"
- "Is anything unclear?"
- "Do you have everything you need?"
What to focus on:
Don't walk through every screen. Focus on:
- New components (not in the design system yet)
- Complex interactions (multi-step flows, animations)
- Edge cases (error states, empty states, loading states)
✅ Step 8: Confirm Developer Sign-Off
The Rule:
Before the meeting ends, explicitly confirm that the developer:
- ✅ Can access the Figma file
- ✅ Can view the component specs
- ✅ Has access to the design tokens (colors, spacing, typography)
- ✅ Knows where to find documentation (copy specs, animation specs, breakpoints)
- ✅ Understands the edge cases and states
- ✅ Has a contact person for questions (you, or a design system owner)
How to confirm:
Ask explicitly:
"Can you confirm you have access to:
- The Figma file (link)?
- The design tokens in code (repo link)?
- The component documentation (Storybook/Zeroheight link)?
And do you understand how to handle the loading, error, and empty states?"
Follow up with a written summary:
Send a Slack message or email with:
- Link to Figma file
- Link to design tokens
- Link to documentation
- Screenshots of key states
- Notes from the walkthrough
Example:
Hey team! Here's everything you need for the new checkout flow:
📐 Figma File: [link]
🎨 Design Tokens: [GitHub repo link]
📚 Component Docs: [Storybook link]
Key Points:
- The payment form has 4 states: Default, Loading, Error, Success
- Error messages are listed on the "Copy Specs" page
- Mobile breakpoint changes the layout to single-column (see Mobile frame)
- Animation spec: 300ms ease-in-out for error message fade-in
Let me know if you have any questions!
Additional Best Practices
Use Design Tokens, Not Hex Codes
Bad:
Button background: #3B82F6
Good:
Button background: primary-600
Why it matters:
- Design tokens are semantic (name describes usage)
- If you change the color later, it updates everywhere
- Developers can reference the token in code
How to implement in Figma:
- Create color styles for every color in your palette
- Name them semantically (e.g.,
primary-600, not blue-600)
- Apply styles instead of raw hex codes
Name Layers Descriptively
Bad:
Frame 1
└─ Group 1
└─ Rectangle 1
Good:
Card / Product
└─ Header
└─ Title
└─ Subtitle
└─ Body
└─ Actions
└─ Button / Primary
└─ Button / Secondary
Why it matters:
- Developers can understand the structure without guessing
- Makes Inspect panel more useful
- Easier to navigate large files
Use Consistent Naming Conventions
Recommended Pattern:
[Component] / [Variant] / [Size] / [State]
Examples:
Button / Primary / Medium / Default
Button / Primary / Medium / Hover
Input / Text / Large / Error
Card / Product / Default
Why it matters:
- Predictable structure
- Easy to find components
- Maps cleanly to code component names
The Zero-Ambiguity Checklist (Quick Reference)
Use this checklist before every handoff:
Pre-Handoff (In Figma)
Specification (Documentation)
Delivery (The Meeting)
Real-World Impact: Before and After
Here's what happened when one team implemented this checklist:
Before (Ambiguous Handoff)
- Dev questions per feature: 15-20
- Design-to-dev handoff time: 2-3 days
- Rework rate: 35% of features required design revision after implementation
- Time to fix inconsistencies: 40 hours/quarter
After (Zero-Ambiguity Checklist)
- Dev questions per feature: 2-3
- Design-to-dev handoff time: 4 hours
- Rework rate: 8% of features required revision
- Time to fix inconsistencies: 5 hours/quarter
Results:
- 87% reduction in follow-up questions
- 77% reduction in rework
- Design team saved 140 hours/year on rework
- Engineering team shipped features 40% faster
Common Mistakes and How to Avoid Them
Mistake 1: "The Figma File is Self-Explanatory"
The Assumption:
"I designed it clearly. Devs should just look at the file."
The Reality:
- Developers aren't designers—they don't know where to look
- Figma shows what, not why or how
- Edge cases aren't obvious
The Fix:
- Always include written documentation
- Walk through the design in a meeting
- Explain the rationale, not just the visuals
The Assumption:
"Let's ship the happy path first. We'll handle errors later."
The Reality:
- "Later" never comes
- Users encounter errors immediately
- Inconsistent error handling erodes trust in the design system
The Fix:
- Design all states upfront (error, empty, loading)
- Include them in the initial handoff
- Make edge cases non-negotiable
Mistake 3: "Developers Should Just Use the Design System"
The Assumption:
"We have a design system. Devs should know what components to use."
The Reality:
- Developers may not know the design system as well as you do
- They may not know which variant to use
- They may copy hex codes instead of using tokens
The Fix:
- Explicitly call out which design system components to use
- Provide links to component documentation (Storybook, Zeroheight)
- Use design tokens in Figma, not raw values
Here's the truth:
Design quality in production is directly proportional to specification quality.
You can have the most beautiful designs in Figma. But if the specs are incomplete, ambiguous, or hard to find, the implementation will be inconsistent, broken, and frustrating.
Zero-ambiguity specs ensure:
- Developers have everything they need (no guesswork)
- Implementation matches design (no drift)
- Design system stays consistent (no one-off hacks)
- Teams move faster (no back-and-forth)
The checklist in this post is your tool for achieving that.
Use it before every handoff. Make it non-negotiable. Your engineering team will thank you.
Want to learn more about design systems and collaboration?
What's in your developer handoff checklist? What do you wish developers understood better about design specs?