3.2 — Figma for developers
Opening scenario
The designer drops a Figma link in Slack. “Here’s the new feed screen, ship it by EOD Friday.” You open it. There are 47 frames. Three are labeled “final,” two are labeled “final-v2,” and one is labeled “final-FINAL-actually-this-one.” Components are nested four deep. Colors are listed as raw hex. You don’t know which frame is the source of truth, which spacing values are intentional vs accidental, what state each component represents, or how to export the icons.
This chapter teaches you to read Figma like an iOS engineer — fast, accurately, and without bothering your designer every 10 minutes.
| Aspect | Detail |
|---|---|
| Tool | Figma — free for individuals, $15/editor/month for orgs |
| Plugin you need | Figma Dev Mode (built-in, requires paid plan in 2024+) |
| iOS UI kits | Apple’s Official iOS Design Kit |
| What you produce | Pixel-accurate SwiftUI/UIKit, asset exports, design tokens |
Concept → Why → How → Code
The Figma object model
Figma’s hierarchy, from outermost to innermost:
- Team → Project → File → Page → Frame → Group / Component instance → Layer
You will mostly live in:
- Pages: tabs at the top — usually one per feature area
- Frames: artboards, each one represents a screen or screen state
- Components: reusable building blocks (button, card, avatar)
- Component instances: a placed copy of a component, possibly with overrides
A component in Figma maps to a SwiftUI View or UIKit UIView. Treat them that way.
Frames vs components vs variants
| Figma concept | Swift analog |
|---|---|
| Frame | A screen or sub-screen (a View’s body) |
| Component | A reusable view (struct ButtonStyle, struct CardView) |
| Variant | An enum-driven state (enum ButtonStyle { case primary, secondary }) |
| Instance | A call site of the component |
| Override | A parameter or .modifier at the call site |
When you see a button with variants primary / secondary / destructive, that becomes:
enum AppButtonStyle { case primary, secondary, destructive }
struct AppButton: View {
let title: String
let style: AppButtonStyle
let action: () -> Void
var body: some View {
Button(title, action: action)
.buttonStyle(.borderedProminent)
.tint(style.tint)
}
}
extension AppButtonStyle {
var tint: Color {
switch self {
case .primary: .accentColor
case .secondary: .secondary
case .destructive: .red
}
}
}
Auto Layout in Figma → HStack/VStack in SwiftUI
Figma’s Auto Layout is the design equivalent of SwiftUI’s stacks. When you select a frame with Auto Layout enabled, the right panel shows:
- Direction: vertical or horizontal →
VStackorHStack - Spacing: gap between children →
spacing:parameter - Padding: inset around children →
.padding(.horizontal, X).padding(.vertical, Y) - Alignment: top/center/bottom × leading/center/trailing →
alignment: - Sizing: hug / fill / fixed → use
.frame()or no frame; “fill” usually means.frame(maxWidth: .infinity)
// Figma: VStack, spacing 12, padding 16, fill width, hug height
VStack(alignment: .leading, spacing: 12) {
Text("Title").font(.headline)
Text("Subtitle").font(.subheadline)
}
.padding(16)
.frame(maxWidth: .infinity, alignment: .leading)
If your designer doesn’t use Auto Layout, gently insist. Without it, every screen is an exercise in eyeballing pixels. With it, the Figma file is the SwiftUI structure.
The Inspect panel (Dev Mode)
Switch Figma to Dev Mode (top right toggle). The right sidebar changes from a designer’s panel to a developer’s panel:
- Code section: shows generated SwiftUI / UIKit / CSS / Android XML for the selected layer
- Properties: width, height, fills, strokes, effects, typography
- Assets: download icons / images as SVG / PDF / PNG @1x/2x/3x
- Variables: design tokens (colors, spacing) with their semantic names
- Comments: redlines, annotations, conversation threads
The generated code is a starting point, not the final answer. It hardcodes pixel values; you should replace them with semantic tokens (Chapter 3.3) and Dynamic Type-aware fonts.
Inspecting spacing, colors, typography
Spacing: hold ⌥ (option) and hover other layers — Figma shows the pixel distance from your selection to the hovered layer. This is how you find the actual gap value, regardless of what the layer panel claims.
Color: click any fill swatch. The popover shows hex + opacity + linked variable name (e.g. color/brand/primary). Use the variable name as your token name in code.
Typography: select a text layer; the right panel shows font family, weight, size, line height, letter spacing. Map these to SwiftUI:
// Figma: SF Pro Display, Semibold, 17pt, line-height 22pt
Text("Hello")
.font(.system(size: 17, weight: .semibold))
.lineSpacing(22 - 17) // SwiftUI's lineSpacing is the *gap*, not total line-height
Better: use semantic text styles (.headline, .body, .subheadline) so Dynamic Type works. The 17pt semibold above is exactly .headline — use that.
Components from Apple’s official iOS UI kit
Apple publishes a free iOS Design Kit on Figma Community. It contains every UIKit / SwiftUI standard component (tab bars, nav bars, sheets, alerts, system colors, SF Symbols). Designers who start from this kit save you weeks of “is this a custom button or a system button?” arguments.
Push your design team to use it. The components are designed to map 1:1 to native controls.
Spec-vs-code discrepancies — the etiquette
When the Figma differs from a HIG-required behavior (e.g. designer made a 32pt tap target; HIG requires 44pt minimum), the HIG wins. Add a Figma comment quoting the HIG rule, ship the HIG-conformant version, and link your designer to the source.
When the Figma differs from technical reality (e.g. designer wants a perfect circle avatar but the image API returns variable aspect ratios), bring it up in handoff with two solutions, not just a complaint.
In the wild
- Apple’s design team ships its WWDC keynote slides from Keynote, but the design specs for first-party apps are in Figma now (as of ~2023, per public job postings).
- Airbnb’s design system (“DLS”) publishes its Figma library to all engineers; the component names match the Swift component names exactly.
- Spotify uses Figma’s variables feature for design tokens, generates JSON via the Figma API, and feeds them into a Style Dictionary build step that outputs
Color+Tokens.swiftand Android XML in the same CI job. - Lyft open-sourced its Figma-to-Swift token generator — worth reading the README to see how a real team automates handoff.
Common misconceptions
- “Figma is for designers; engineers don’t need to learn it.” Wrong. You’ll spend 30% of your handoff time in Figma. Learning the inspect panel saves hours every sprint.
- “Dev Mode auto-generated code is production-ready.” It is not. It hardcodes pixel values, uses hex colors, ignores Dynamic Type. Use it as a structural starting point.
- “Figma replaces communication with designers.” It does not. It removes the trivial questions (what’s the spacing?) so you can spend conversation budget on the real questions (what’s the empty state? what’s the error state? what’s the animation?).
- “I can just screenshot the Figma and pixel-compare.” Screenshots hide the structure. You need to inspect Auto Layout, components, and variables to build the right hierarchy.
- “All assets export from Figma at 1x; the designer should re-export 2x and 3x.” No — you export. Dev Mode → Assets → check the @1x/@2x/@3x boxes → drop into Xcode. The designer’s time is for design.
Seasoned engineer’s take
Treat Figma as read-only code. Open it with the same rigor as a Swift file. Find the source-of-truth frame (usually labeled “✅ Ready for dev” or in a specific page). Ignore the dozens of exploration frames unless your designer points to one.
Insist on a single design tokens source. If colors and spacing live in Figma variables, you can write (or use) a script that pulls them via the Figma API and outputs DesignTokens.swift automatically. Your designer changes the brand color in Figma; your CI ships a new build with the updated color. No copy-paste, no drift.
When a designer hands you a Figma without Auto Layout, components, or variables, you’re not getting design — you’re getting decoration. Push back kindly: “Can we adopt Figma Auto Layout for handoff? It makes implementation 2x faster.” This is a respectful, evidence-based request.
TIP: Install the Figma Mac app (not the browser version). The native pencil/keyboard handling is much better, and it has offline mode.
WARNING: Never trust pixel measurements from screenshots — always check the actual Figma file. Designers iterate; screenshots go stale.
Interview corner
Junior-level: “Have you used Figma? What’s Dev Mode?”
Yes — Dev Mode is the developer-facing view that exposes generated code, asset downloads, design tokens (variables), and pixel measurements. It’s how engineers extract specs without needing a designer to walk through every screen.
Mid-level: “How would you structure a handoff process between design and engineering?”
Single source-of-truth file. Designers mark frames as “ready for dev” (status field). Components and variables required — no raw hex. Engineers use Dev Mode to inspect; redlines and questions live as comments on the frame. Token names map 1:1 to code. Friday handoff meetings to walk the next sprint’s screens.
Senior-level: “Your design system is in Figma but your codebase has drifted — colors don’t match anymore. How do you fix it?”
Audit the gap (list every color in code vs Figma variables). Pick a source of truth (Figma). Use the Figma API to export variables as JSON, run through Style Dictionary or a custom script to generate DesignTokens.swift. Add to CI so token drift is caught on every PR. Migrate existing call sites incrementally, by feature. Add a SwiftLint rule banning raw hex colors.
Red flag in candidates: Saying “I don’t open Figma, I just ask the designer for the values” — signals a junior workflow that doesn’t scale.
Lab preview
You’ll implement a Figma design pixel-accurately in SwiftUI in Lab 3.1 — Figma to SwiftUI.