Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions docs/blog/2026-02-01-figma-to-code-one-command.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ $ ralph-starter run --from figma \
--project "https://figma.com/file/ABC123/Dashboard" \
--figma-mode components \
--figma-framework react \
--loops 5 --test --commit
--max-iterations 5 --test --commit

🔄 Loop 1/5
→ Fetching from Figma API... 12 frames, 34 components found
Expand Down Expand Up @@ -83,14 +83,28 @@ Setup is dead simple, just a personal access token from Figma:
ralph-starter config set figma.token figd_xxxxx
```

:::tip Figma Plan Matters
The free/starter plan limits you to **6 API requests per month** -- that is barely one fetch. For real development, you need a **Professional plan with a Dev seat** ($12/month), which gives you 10+ requests per minute. Responses are cached locally so repeated runs are free.
:::

The reason this works at all is [the loop](/blog/my-first-ralph-loop). The agent does not just generate code and stop. It generates, runs tests, sees what broke, fixes it, runs again. By loop 3 or 4 you have components that actually render and pass lint. Same [Ralph Wiggum technique](/blog/ralph-wiggum-technique) I use for everything else -- just pointed at a design file instead of a GitHub issue. I did not even plan it this way. It just... worked.

Want to try it with your own Figma file?

```bash
npx ralph-starter init
ralph-starter config set figma.token figd_your_token_here
ralph-starter run --from figma --project "your-figma-url" --figma-mode components --figma-framework react --loops 5
ralph-starter run --from figma --project "your-figma-url" --figma-mode components --figma-framework react --max-iterations 5
```

You can also pick your model with `--model`. Sonnet is fast and cheap for UI work, Opus is better for complex state logic:

```bash
# Fast + cheap (recommended for most Figma workflows)
ralph-starter run --from figma --project "your-figma-url" --figma-mode components --model claude-sonnet-4-5-20250929 --max-iterations 5

# Maximum quality
ralph-starter run --from figma --project "your-figma-url" --figma-mode components --model claude-opus-4-6 --max-iterations 3
```

## References
Expand Down
90 changes: 90 additions & 0 deletions docs/docs/sources/figma.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ Create a custom mapping file to control how Figma content maps to your component
| `--figma-target` | Target directory (content mode) | Path (e.g., `src/pages`) |
| `--figma-preview` | Preview without applying (content mode) | Flag |
| `--figma-mapping` | Custom mapping file (content mode) | File path (e.g., `mapping.json`) |
| `--model` | AI model for the coding agent | Model ID (e.g., `claude-sonnet-4-5-20250929`) |

## Figma URL Formats

Expand Down Expand Up @@ -247,6 +248,30 @@ ralph-starter integrations fetch figma "ABC123" --figma-mode assets
# Run the generated curl commands to download
```

### Choose Your Model

Use `--model` to pick which AI model implements the design. Sonnet is fast and cost-effective for most UI work; Opus produces more nuanced implementations for complex layouts:

```bash
# Fast iteration with Sonnet (recommended for most Figma workflows)
ralph-starter run --from figma \
--project "https://figma.com/file/ABC123/Dashboard" \
--figma-mode components \
--model claude-sonnet-4-5-20250929 \
--max-iterations 5

# Maximum quality with Opus
ralph-starter run --from figma \
--project "https://figma.com/file/ABC123/Dashboard" \
--figma-mode components \
--model claude-opus-4-6 \
--max-iterations 3
```

:::tip Model Selection for Figma
**Sonnet** is the sweet spot for Figma-to-code. It handles component structure, layout, and styling accurately at ~5x lower cost and faster iteration speed. Use **Opus** when you need complex state logic or intricate responsive behavior alongside the UI.
:::

## Test Connection

Verify your authentication:
Expand All @@ -255,8 +280,72 @@ Verify your authentication:
ralph-starter integrations test figma
```

## Rate Limits & Caching

### Figma API Rate Limits

Figma enforces rate limits based on your **plan tier** and **seat type**. This matters because it determines how many API requests you can make per minute (or per month).

| Seat Type | Starter | Professional | Enterprise |
|-----------|---------|-------------|------------|
| Collab/Viewer (low) | 6/month | 5/min | 10/min |
| Dev/Full (high) | 10/min | 15-50/min | 20-100/min |

:::warning Free & Starter Plans
On the **Starter plan with a Collab/Viewer seat** (`limit-type=low`), you get only **6 requests per month**. Each `ralph-starter run --from figma` uses 2-4 API calls, so you can exhaust your budget in 1-2 runs. Upgrade to a **Professional plan with a Dev seat** ($12/month) for 10+ requests per minute.
:::

### Community Files

When you access a **community file** (duplicated from the Figma Community), the **file owner's plan** determines your rate limits -- not your own plan. If the original author is on a free/starter plan, you'll be limited to 6 requests per month regardless of your plan.

**Fix:** Duplicate the file to your own workspace. This makes you the owner and applies your plan's limits.

### Response Caching

ralph-starter automatically caches Figma API responses in `~/.ralph/figma-cache/` with a 1-hour TTL. This means:

- **First run** fetches from the API and populates the cache
- **Subsequent runs** (within 1 hour) use the cache with zero API calls
- **Rate limited (429)?** Falls back to stale cache if available

This is especially useful for iterative development -- fetch once, then run the coding loop as many times as you want without touching the API.

To clear the cache and force a fresh fetch:

```bash
rm -rf ~/.ralph/figma-cache/
```

### Debugging API Issues

Use the `RALPH_DEBUG` environment variable to see every API request, response status, and rate limit headers:

```bash
RALPH_DEBUG=1 ralph-starter run --from figma --project "your-figma-url"
```

This shows:
- Each API endpoint being called
- HTTP status codes and retry-after values
- Plan tier (`x-figma-plan-tier`) and limit type (`x-figma-rate-limit-type`)
- Cache hits and stale cache fallbacks

## Troubleshooting

### "Figma API blocked for ~N day(s)"

This means CloudFront (Figma's CDN) has blocked your IP after too many rate-limited requests. The `retry-after` header shows days, not minutes.

**Solutions (pick one):**
1. **Upgrade your Figma plan** to Professional with a Dev seat ($12/month) -- gives you 10+ req/min instead of 6/month
2. **Use a VPN** to get a fresh IP, fetch once to populate the cache, then disconnect
3. **Wait** for the block to expire (shown in the error message)

### "Figma API rate limit hit"

A transient rate limit (not a CDN block). ralph-starter will automatically retry once after respecting the `retry-after` header. If it fails again, wait 1-2 minutes and try again.

### "Invalid Figma token"

Your token may have expired or been revoked. Create a new token in Figma settings.
Expand All @@ -278,3 +367,4 @@ Assets are detected by name patterns. Rename your icon frames to include "icon",
- **Variables API** requires Figma Enterprise plan (falls back to styles)
- **Image export URLs** expire after 30 days
- **Large files** may be slow; use `--figma-nodes` to target specific frames
- **Starter plan (Collab seat)** limited to 6 API requests/month -- use caching or upgrade to Professional
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@
"yaml": "^2.7.0",
"zod": "^4.3.6"
},
"optionalDependencies": {
"sharp": "^0.33.0"
},
"devDependencies": {
"@biomejs/biome": "^2.3.13",
"@commitlint/cli": "^20.3.1",
Expand Down
Loading