Figma To Mobile
Convert Figma designs to mobile UI code. Supports Android (Jetpack Compose, XML) and iOS (SwiftUI, UIKit). Use when a user provides a Figma link and wants mo...
技能说明
name: figma-to-mobile description: > Convert Figma designs to mobile UI code. Supports Android (Jetpack Compose, XML) and iOS (SwiftUI, UIKit). Use when a user provides a Figma link and wants mobile layout code. Extracts design tokens via Figma REST API, asks clarifying questions, then generates production-ready code files. Optionally inspects local project resources for accurate color/string matching. metadata: { "openclaw": { "requires": { "bins": ["python3"], "env": ["FIGMA_TOKEN"] }, "primaryEnv": "FIGMA_TOKEN", "install": [ { "id": "python-requests", "kind": "shell", "command": "pip3 install requests", "label": "Install Python requests package", }, ], }, }
Figma to Mobile
Convert Figma designs to mobile UI code with interactive clarification.
Supported: Android Compose, Android XML, iOS SwiftUI, iOS UIKit.
Prerequisites
FIGMA_TOKENenvironment variable set (Figma > Settings > Personal Access Tokens)- Python 3.8+ with
requestspackage
Trigger & Input
This skill activates when a user provides a Figma link and explicitly asks for code conversion (e.g. "convert this to Compose", "generate XML for this design"). Do NOT activate if the user merely shares a Figma link for reference without requesting code generation.
The user may also include inline hints alongside the link, such as:
- Target platform: "Android XML", "Compose", "SwiftUI", "UIKit"
- Layout preferences: "use ConstraintLayout", "prefer StackView"
- Component notes: "the switch is our custom CompactSwitch", "this is a dynamic list"
- Any other context about the design
If the user provides hints, respect them and skip the corresponding questions. For example, if the user says "Android XML, the 3 cards are a RecyclerView list", do NOT ask about output format or whether the cards are dynamic/static.
Workflow
Step 1: Fetch & Analyze
When user provides Figma link(s):
-
Determine the input type:
A. Link without specific node-id (no
node-id, ornode-id=0-1): This link points to the entire page, not a specific frame. Tell the user:This link points to the whole page. Please select the frame you want in Figma, right-click it, and choose "Copy link to selection", then send that link. If you want to convert multiple frames, send multiple links.
B. Single frame link (has specific
node-id): Runscripts/figma_fetch.py "<url>"→ returns that frame's design data. Proceed to analysis.C. Multiple links (user sends 2+ URLs): First, determine the relationship by examining frame names and user context:
-
Same page, different visual states (e.g. "首页-有banner" and "首页-无banner"): Use
--comparemode to fetch all and get a diff summary. Generate multi-state code (conditional visibility, state switching). -
Parent page + overlay/drawer (e.g. "首页" + "首页-抽屉-xxx"): Generate each as an independent layout file. Then tell the user the relationship:
Frame 1 ("首页") and Frame 2 ("首页-抽屉") look like a main page + side drawer. I've generated two separate layout files. How you wire them together (DrawerLayout, Navigation, etc.) depends on your project architecture.
The Skill's job is generating UI layout code, not deciding architecture (Activity vs Fragment vs Navigation).
-
Different independent pages (e.g. "首页" + "设置页" + "个人中心"): Process each independently. Fetch them one at a time with a pause between requests to avoid rate limiting. Present a summary of all pages, then ask which to convert first (or convert all sequentially).
-
Not sure: Ask the user — "These frames look related but I'm not sure how. Are they different states of the same page, a page with an overlay, or independent pages?"
Rate limit protection for multiple links: When fetching multiple nodes, wait 2-3 seconds between requests. Never fire more than 2 requests in parallel.
-
-
If the link has no specific node-id, ask the user to re-copy from the specific frame (see A above). Do NOT call the API.
-
Analyze the structure: identify sections, repeated patterns, component types
-
Note INSTANCE nodes — they indicate reusable components. Check
variantPropertiesfor component state (e.g. State=Default, Size=Large) — these map to multi-state code -
Note gradient/shadow data — flag for the user if complex
-
Apply Figma node interpretation rules before generating code
Detailed interpretation rules: Read references/figma-interpretation.md
Step 1.5: Structure Summary
Before asking any questions, present a brief structure summary to the user so they can confirm your understanding:
I see: [navigation bar with back button + title] → [2 content sections: user profile card, settings list (8 items)] → [bottom action button]. Total ~25 nodes.
Keep it to 2-3 lines. Mention:
- Major sections identified (nav bar, content areas, footer)
- Repeated patterns ("8 similar list items", "3 tab labels")
- Notable elements (gradients, complex illustrations, stacked cards)
If the user says "that's wrong" or corrects the structure, adjust understanding before proceeding to Step 2.
If the design has ≤10 leaf nodes (visible elements that map to actual views), skip this step — the structure is simple enough to proceed directly.
Step 2: Confirm & Clarify
Question priority (strict order — ask earlier questions first):
-
Output format (MUST ask first unless user already specified) → Android XML / Compose / SwiftUI / UIKit This determines all subsequent analysis phrasing and code output.
-
Structural ambiguities (only ask what you're genuinely unsure about) → "These N items look similar — dynamic list or fixed layout?" → "This area: single image asset or icon-on-background combo?"
-
Component choices (only if platform-relevant) → "Any custom components to use? (otherwise I'll use platform defaults)"
Rules for questions:
- Skip any question the user already answered via inline hints
- Max 3-5 questions total, fewer is better
- Each question gives concrete options with one-line pros/cons
- Every question includes an open option: "or tell me more about this"
- Use natural language, no JSON or technical dumps
- If everything is clear (user gave full context + simple structure), skip Step 2 entirely
Confidence guide — when to ask vs. when to just generate:
- ≥3 sibling nodes with similar structure → likely a list → ASK (dynamic vs static)
- INSTANCE nodes sharing same componentId → reusable component → MENTION but can default
- Single clear hierarchy, no ambiguity → high confidence → SKIP questions, go to Step 3
- Gradient/complex shadow in design → MENTION in summary ("I see a gradient here, I'll approximate it as X")
Step 2.5: Project Scan (optional, requires consent)
If the target project is available locally and you want to match Figma colors/strings/components to existing project resources, you may run a project scan.
⚠️ Before scanning, you MUST tell the user and get explicit consent:
"I can scan your project directory to look up existing colors, strings, and components for more accurate code generation. This only reads resource files — it won't modify anything. Which project directory should I scan? (Or skip this step.)"
Only proceed after the user provides the path. Do NOT scan without explicit consent.
python scripts/project_scan.py /path/to/project --json --output scan-report.json
What the scan reads: colors, strings, styles, drawables, images, and custom View classes. It does NOT modify any files.
How to use scan results in code generation: Read references/scan-usage.md
If the user declines or has no local project available, skip this step and hardcode all values directly in the generated code.
Step 3: Generate Code
After user confirms (or if no questions needed), generate code files.
Detailed generation rules: Read references/generation-rules.md
If multiple files are needed, output each with a clear filename header:
📄 activity_notification_settings.xml
[code]
📄 item_expert_notification.xml
[code]
Step 4: Iterate & Capture Feedback
After showing code, ask briefly:
Matches the design? Any adjustments?
The user can then give feedback to refine the output. Common iterations:
- "间距大了" → adjust specific spacing
- "Switch 换成我们的 CustomSwitch" → swap component
- "把标题栏去掉" → remove section
- "换成 Compose 版本" → regenerate in different format
- "颜色不对,这里应该是 #333333" → fix specific values
Continue iterating until the user is satisfied.
Iteration output rule:
- If the file has already been written to disk → read the current file, apply only the minimal patch, output just the changed lines with clear context (file path + line range). Do NOT regenerate the whole file.
- If the code only exists in the conversation (not written to disk) → output only the changed snippet with a comment indicating where it replaces (e.g.,
// replaces lines 12-18 in activity_main.xml). Do NOT repeat the entire file. - Only regenerate the full file if the user explicitly asks (e.g., "重新生成完整文件", "show me the full file").
⚠️ Feedback logging is opt-in only: Before logging any correction, you MUST ask the user:
"I can log this correction to
feedback-log.mdto improve future output. It stores the issue, before/after code, and platform info. OK?"
Only proceed if the user explicitly agrees. If they decline, skip logging entirely and continue fixing the issue.
Feedback capture (opt-in):
If the user agrees, log the correction to feedback-log.md in the project root (create if it doesn't exist). Each entry follows this format:
## YYYY-MM-DD HH:MM
- **Platform**: Android XML / Compose / SwiftUI / UIKit
- **Figma node type**: (e.g., FRAME with icon, Tab bar, Button group)
- **Issue**: Brief description of what was wrong
- **Before**: What the agent generated (snippet or description)
- **After**: What the user wanted (snippet or description)
- **Rule candidate**: (optional) If this correction suggests a general pattern rule, note it here
Log entries should be:
- Concise — only the relevant diff, not entire files
- Categorized — always include platform and Figma node type for later analysis
- Actionable — focus on the mapping error, not cosmetic preferences (e.g., "user prefers 16dp" is not a rule; "VECTOR compositions should be single ImageView" is)
Do NOT log:
- One-off personal preferences (specific color choices, naming conventions)
- Corrections to non-mapping issues (typos, import statements)
- Feedback the user explicitly says is project-specific, not general
Periodically (or when asked), run scripts/feedback_analyze.py to identify patterns and generate rule candidates.
Error Handling
- FIGMA_TOKEN not set (script outputs
FIGMA_TOKEN_NOT_SET) → do NOT ask the user to paste their token into chat. Instead:- Tell the user they need a Figma Personal Access Token (starts with
figd_) - Tell them where to get it: Figma → avatar (top-left) → Settings → Security → Personal Access Tokens
- Ask them to set
FIGMA_TOKENas a user environment variable (Windows:setx FIGMA_TOKEN "figd_xxx", macOS/Linux: addexport FIGMA_TOKEN="figd_xxx"to~/.zshrcor~/.bashrc), then restart their terminal and retry
- Tell the user they need a Figma Personal Access Token (starts with
- FIGMA_TOKEN invalid (API returns 403/401) → token may have expired or been revoked. Ask the user to regenerate a new token (same path: Figma → Settings → Security → Personal Access Tokens) and set it locally, then retry.
- Invalid URL → show valid URL example:
https://www.figma.com/design/<fileKey>/<name>?node-id=<id> - API error → show error message, suggest checking network/proxy
- Node too large (>200 children) → suggest selecting a smaller frame
- Depth auto-increased → the script auto-retries with deeper depth if it detects truncated children. Inform user if this happens ("I needed to fetch deeper to get all details").
如何使用「Figma To Mobile」?
- 打开小龙虾AI(Web 或 iOS App)
- 点击上方「立即使用」按钮,或在对话框中输入任务描述
- 小龙虾AI 会自动匹配并调用「Figma To Mobile」技能完成任务
- 结果即时呈现,支持继续对话优化