agentsclimarketplace

Figma to swiftui

Skill Emasoft/emasoft-complete-ios-app-authoring/skills/figma-to-swiftui

Translate Figma designs into native SwiftUI code (iOS 26 / Swift 6) by reading the Figma file directly through the Figma MCP — no PNG exports or screenshots. Sets up the MCP read→build→preview→compare→iterate loop, maps Figma layout/tokens to native components and HIG values, enumerates screen states, and verifies results numerically with accessibility frames. Use when building or matching Figma frames in SwiftUI, polishing a screen to a comp, batch-importing designed screens, or extracting design tokens. Triggers: "build this Figma frame", "match this Figma design in SwiftUI", "turn my Figma into iOS code", "figma to swiftui", "extract design tokens from Figma".From its SKILL.md

Install
npx -y skills add Emasoft/emasoft-complete-ios-app-authoring --skill figma-to-swiftui

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

19.5 KB, as published. Nobody here has run it

Figma → SwiftUI

Get Claude Code to read your Figma designs directly and translate them into native SwiftUI. No screenshots. No PNG uploads. The Figma MCP gives Claude design structure — frame dimensions, hierarchy, text content, colors, spacing, component structure — which you act on, not pixels you guess at.

Know which MCP you're on. The community GLips figma-developer-mcp returns a parseable layout dump. The official Figma Dev-Mode MCP's get_design_context returns React JSX + Tailwind CSS by default — that is design intent, not code to paste. Extract the numbers out of the Tailwind classes and translate; never transliterate the JSX into Swift. The full translation tables and value legend are in references/react-tailwind-to-swiftui.md. (Configure Code Connect — references/code-connect-swiftui.md — and the official server returns your actual SwiftUI snippets instead.)

This skill covers the full loop: connect the MCP stack, reference the right frames, translate to native SwiftUI, map design tokens correctly to HIG values, cover every screen state, and verify the result numerically before claiming it's done.

When to use

  • You designed a screen in Figma and want Claude Code to build it.
  • You're polishing an existing screen to match a refined Figma comp.
  • You're adding screens that were designed before being built.
  • You're batch-importing several screens from one Figma project.
  • You need to extract a design system (colors / type / spacing / radius) out of a Figma file into Swift tokens.

When NOT to use

  • The design lives only as a flat image — ask for the Figma file or frame link. A PNG loses all structure; the MCP is what makes this skill work.
  • You're building from a written description with no design — use a normal "build screen X" prompt; you don't need Figma reading.

Prerequisites

  • Figma MCP connected to Claude Code (see "MCP stack" below).
  • Your Figma file organized with named frames, one screen per frame (not random artboards). Layer names carry into the MCP output — name them well and Claude gets free structure.
  • Ideally the full iOS MCP stack so Claude can build and visually verify its own output (Sosumi for Apple docs, XcodeBuildMCP for builds, the Xcode MCP Bridge for preview rendering). See references/mcp-stack-setup.md.

The closed loop (the whole point)

With the full MCP stack, steps 2–8 happen without your intervention — you describe and review; Claude handles the middle:

1. You point at a Figma frame and describe what it DOES (behavior).
2. Claude reads the frame via Figma MCP (layout, text, color, hierarchy).
3. Claude checks the correct SwiftUI API via Sosumi (HIG, modifiers).
4. Claude writes native SwiftUI.
5. Claude builds via XcodeBuildMCP (catches compile errors).
6. Claude renders a #Preview via the Xcode MCP Bridge (sees its output).
7. Claude compares the preview to the Figma frame.
8. Claude iterates on its own until layout + hierarchy match.
9. You review the final result.

Figma gives the "what it looks like." You give the "what it does." The MCP provides layout/text/color/hierarchy but not interaction, navigation, state changes, or animation — those you must describe. That's why behavior descriptions still matter even with a perfect design read.


How to reference Figma frames

Be specific. Ambiguous references ("the one with the green button") waste a round trip.

MethodHow
Frame URLRight-click the frame in Figma → Copy link → paste into your prompt.
Node IDIn the Figma URL, the node id appears after node-id=. Reference it directly.
File + frame name"In my Figma file [URL], find the frame called 'Settings Main'."

Never paste the whole file without naming frames — too much context. Never reference by visual description — use a URL or node id.


Prompt templates

You do not paste code snippets or Apple-docs links. Your CLAUDE.md (see "Project setup") carries the standing rules. Describe the screen.

New screen:

Build [Screen Name] based on this Figma frame: [URL or node-id].

Read the frame's layout, text content, spacing, and hierarchy. Use native
SwiftUI components for everything (CLAUDE.md has the component rules). The
Figma design shows visual INTENT — match the layout and hierarchy, but use
system-standard spacing and native component behavior rather than
pixel-exact replication of every dimension.

It does [describe behavior: what tapping/swiping does, where nav goes,
empty/loading/error states].

Polishing an existing screen:

Refine [Screen Name] to match this Figma frame: [URL or node-id].

The screen already works. Adjust layout, spacing, typography weight, and
visual hierarchy to match the Figma design. Do NOT change functionality or
navigation. Do NOT replace native components with custom ones.

Batch import:

Here are the Figma frames for the Settings flow:
- Settings Main: [URL]
- Settings Notifications: [URL]
- Settings Appearance: [URL]

Build all three. Each is a standard grouped List with sections and rows
(CLAUDE.md has navigation patterns). The gear icon on the home screen is
the entry point.

The 80/20 rule — match intent, not pixels

Match the design at the layout and hierarchy level. Don't fight SwiftUI's layout system to hit every pixel — that produces brittle, non-adaptive UI that breaks on a different screen size.

Match these:

  • Content hierarchy (what's bigger / bolder / more prominent)
  • Layout direction (horizontal vs vertical groupings)
  • Text content and approximate weight
  • Brand/accent color values
  • Overall spacing feel (tight vs airy)

Let SwiftUI own these:

  • Exact padding values (system defaults are usually right)
  • List row heights (system standard beats forced values)
  • Safe-area insets, keyboard avoidance
  • Navigation-bar and tab-bar styling
  • Liquid Glass material on chrome (iOS 26 system default)

The most common failure is a designer's mock specifying 17pt padding and the agent hardcoding .padding(17) everywhere. Map "tight ~ 8pt, standard ~ 16pt, section ~ 24pt" to the HIG 8-pt grid (see references/hig-tokens.md), and reach for .padding() defaults unless the design clearly diverges.

Importing from a non-Figma / web tool? A CSS/web export, a WeChat/WXSS or Lanhu spec, or an @Nx raster brings two traps Figma doesn't: the numbers are in a different unit (rpx ÷ 2 → pt, CSS px → pt 1:1, @Nx ÷ N), and a dimension equal to the canvas/device width is really a fill — emit .frame(maxWidth: .infinity), never a literal 375/393. CSS-property → SwiftUI-modifier recipes, the container-type triggers, and the "strip the fake status bar" rule are in references/web-import-to-swiftui.md.


Native-first (non-negotiable)

Claude's default is to build custom views. Reject that. If SwiftUI has a native component, use it. Native components inherit Dynamic Type, dark mode, haptics, system animations, VoiceOver, safe-area handling, and localization for free; every custom view must re-implement all of it.

The decision test for every element the design shows:

1. Does SwiftUI have a built-in component?  → use it
2. Does SwiftUI have a modifier for this?   → use it
3. Can native components compose to this?   → do that
4. Truly no native way?                     → custom, but justify + list it

Quick map from "what the Figma shows" to "what to write":

Figma showsUseNOT
A list of itemsList / LazyVStackcustom ScrollView+VStack
Bottom tabsTabViewcustom HStack of buttons
A button opening optionsMenucustom popover
A sliding toggleTogglecustom switch
Segmented choicePicker (.segmented)custom segmented control
Text inputTextField / TextEditorcustom input
A sheet sliding up.sheet + .presentationDetentscustom modal
Long-press options.contextMenucustom gesture
Search bar.searchablecustom field
Pull to refresh.refreshablecustom gesture
Progress ring/barProgressView / Gaugecustom spinner
Alert / confirm.alert / .confirmationDialogcustom view
Grouped settingsForm / List(.insetGrouped)custom VStack
An iconImage(systemName:) (SF Symbols)bundled PNG icon
Share actionShareLinkcustom share
Color pickerColorPickercustom grid
Paywall content.subscriptionStoreViewcustom purchase UI

The fuller map and the UIKit-bridge escape hatches live in references/native-first-and-bridging.md.

Modern state & concurrency (iOS 17+ / Swift 6) the generated code must use: @Observable (not ObservableObject), @State for local view state, @Binding for passed-down state, @Query for SwiftData, @Environment for shared state; async/await + .task (not .onAppear + completion handlers); @MainActor on view models. Full table in the bridging reference.

Red flags in generated output (even if you can't read Swift): UIViewRepresentable/UIHostingController where unnecessary, GeometryReader for basic layouts, Custom<Thing> when a native component exists, hardcoded .frame(width: 393), custom tap/long-press gesture recognizers.


Cover every state — not just the happy path

A Figma frame is one state. Real screens have many. Before you call a screen done, enumerate the states the design (and the behavior you described) implies, and build them. The minimum set per screen plus the per-type additions (forms, lists, detail, flow, permission, first-run, dark mode) is in references/screen-states-checklist.md.

The two most-forgotten states, every time:

  • Permission states for anything touching camera / photos / location / notifications: Granted / Denied / NotDetermined / Prompting.
  • Empty / Loading / Error for any data-backed screen.

In SwiftUI, don't build light + dark duplicates — bind colors to the asset catalog / Color semantic colors and let the system switch. Build a single "Theme Showcase" preview for a light/dark spot-check.


Extracting design tokens from a Figma file

When the task is "pull the design system out of Figma" (colors, type, spacing, radius) rather than "build one screen", the discipline is:

  1. Register what already exists — Figma Variables / Styles / Components already in the file. Read them; don't recreate them.
  2. Find recurring raw values — a color / type pair / radius / spacing value used ≥ 3 times is a token candidate. A one-off is not.
  3. Map to HIG semantics — emit Swift tokens named for their role (label, secondaryLabel, accent, systemBackground, spacing s16, radius r12), backed by the asset catalog for light/dark, not literal hexes scattered through views.
  4. Never invent values — if the design doesn't specify a color, use the iOS system default. Only define what diverges.

The full extraction recipe (with the Figma Plugin-API scan code and the ≥3-occurrence dedup logic) is in references/figma-token-extraction.md. The HIG hard data you map onto (typography scale, 8-pt spacing, radius, touch targets, semantic colors, safe areas, shadows, the Figma-shadow→native blur÷2 rule) is in references/hig-tokens.md.

The MCP gives layout + tokens but cannot export asset bytes — for the actual cover images / illustrations / tintable icons going into Assets.xcassets, pull them via the Figma REST v1/images endpoint: references/asset-bytes-rest.md (two round-trips, hyphen→colon node ids, per-scale imageset loop, chip-strip for template SVGs, token hygiene).


Project setup that makes this reliable

Add a ## Build and Preview Loop block to your project CLAUDE.md so Claude self-verifies before showing you anything:

## Build and Preview Loop
After building or modifying any screen:
1. Build with XcodeBuildMCP. Fix any compile errors.
2. Render a #Preview with RenderPreview. Check the layout.
3. If you provided a Figma frame, compare the preview to the design.
4. Only tell me the screen is ready after the build succeeds AND the
   preview looks correct.

## Component Rules
- Use native SwiftUI components for everything unless a custom component is
  explicitly listed in the Custom Components section.
- Before creating a custom view, check for a built-in component first.
- Do not wrap native components in custom abstractions.
- Use @Observable, @State/@Binding, async/await + .task, @MainActor on VMs.

## Visual Design
See DESIGN_SYSTEM.md for colors, typography, and assets. When in doubt, use
iOS system defaults; apply custom values only where DESIGN_SYSTEM.md defines
them.

This drops most screens from 2–3 feedback rounds to 0–1. Keep CLAUDE.md under ~500 lines — Claude loads the whole file every session, and bloat dilutes the rules that matter. The DESIGN_SYSTEM.md shape (define only what diverges from iOS defaults) is in references/design-system-doc.md.

Never let Claude modify .pbxproj files when adding new screen files — that corrupts the project. Add files through Xcode or a tool that knows the project format.


Verify numerically before claiming "done"

Eyeballing a preview is unreliable for layout. Humans cannot see 16pt vs 21pt padding, 2pt off-center drift, or 40pt vs 44pt button heights — all of which are real bugs that ship in apps that "looked fine." Replace "looks right" with a number.

After building from a frame:

  1. Build clean via XcodeBuildMCP (SUCCEEDED, zero errors). Ignore phantom SourceKit diagnostics that don't appear in the build log — that's lag.
  2. Screenshot / render the preview — gut check, never sufficient alone.
  3. AX snapshot (snapshot_ui returns every visible element's AXFrame x/y/width/height in real screen coordinates). Verify layout with math:
    • Is the child centered in / aligned to / offset from its parent?
    • Is spacing between siblings equal?
    • Is anything off-screen?
    • Does padding match the design spec?
    Button AXFrame: x=80, width=242 on a 402pt-wide screen
    right edge = 80 + 242 = 322 ; right margin = 402 - 322 = 80
    left margin = 80 → difference 0 → centered ✓
    
    If the math doesn't check out, the fix isn't done. Centered is a number, not a feeling.
  4. Commit only after the numbers match.

Drive any verification taps by accessibility id / label, not coordinates — coordinates break the moment layout shifts; labels survive. Run the check on more than one device width (SE, mini, and a Pro Max) — layout bugs love the narrow screens. Full loop (with simulator-state-reset recipes for first-run flows) in references/verification-loop.md.


Anti-patterns

TemptationWhy it fails
"Match every pixel exactly"You fight SwiftUI's layout and ship brittle, non-adaptive UI
Exporting PNGs and uploading themLoses all structure; the MCP gives design structure (layout dump or React+Tailwind) you can act on
Pasting the official MCP's React+Tailwind output into a .swift fileIt's design intent, not code — extract the values, translate via references/react-tailwind-to-swiftui.md
Referencing frames by descriptionAmbiguous; use URLs or node ids
Sending the whole Figma fileToo much context; reference specific frames
Expecting interactions inferred from a static frameFrames are static; always describe what taps/swipes/nav do
Hardcoding the design's literal padding/hex everywhereMap to the 8-pt grid + semantic tokens; let .padding() defaults work
Building only the Default stateShip Empty/Loading/Error + permission + dark mode too
Claiming a layout fix done on a screenshot gut-checkVerify the AXFrame math; the "obvious" fix is where regressions hide
Letting Claude edit .pbxprojCorrupts the project; add files through Xcode

References

  • references/react-tailwind-to-swiftui.md — translate the official MCP's React+Tailwind output: the Tailwind value legend, full Flexbox/Grid/color/type/border/shadow tables, iOS 26 glass indicators, CSS/Framer-Motion → SwiftUI, and a Tailwind→UIKit table.
  • references/mcp-stack-setup.md — connect Figma MCP (GLips vs official) + Sosumi + XcodeBuildMCP + Xcode MCP Bridge; the official server's 16 tools / rate limits / URL parsing; extraction validation + re-extract triggers; the mcpbridge tool surface; failure playbook; the SwiftUI→Figma reverse workflow.
  • references/code-connect-swiftui.md — FigmaConnect structs + property decorators so get_design_context returns your SwiftUI directly (the acceleration layer; requires the official MCP).
  • references/asset-bytes-rest.md — pull raster/vector asset BYTES via the Figma REST v1/images endpoint (the MCP can't export bytes): imageset loop, tintable-SVG setup, chip-strip, token hygiene.
  • references/web-import-to-swiftui.md — importing from a non-Figma source (CSS/web, WXSS/Lanhu rpx, @Nx): unit conversion, canvas-width=fill rule, CSS→SwiftUI recipes, container-type triggers, strip the fake status bar.
  • references/hig-tokens.md — HIG hard data: typography scale, 8-pt spacing, radius, 44×44 touch targets, semantic colors (light/dark), safe areas, shadows (incl. Figma blur÷2 + alpha separation), the UIKit Figma-fidelity tolerance gate, font availability + EN↔CJK weight equivalence.
  • references/native-first-and-bridging.md — full native-component map, container-type triggers, modern state/concurrency rules, and the three legitimate UIKit-bridge escape hatches.
  • references/screen-states-checklist.md — per-screen-type state enumeration so no state ships missing.
  • references/figma-token-extraction.md — extract a design system from a Figma file: Plugin-API scan code + ≥3-occurrence dedup.
  • references/design-system-doc.md — the DESIGN_SYSTEM.md shape (define only what diverges from iOS defaults) + the brand-sourcing Ask→Search→Download→Verify→Write flow.
  • references/verification-loop.md — the build→screenshot→AX→math-check loop and simulator-state-reset recipes.

Keep looking

Skills are one crate of 626,194. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.