/figma-to-react
Use when the user wants to extract Figma designs into production-ready React or Next.js components with TypeScript, Tailwind CSS, and pixel-perfect accuracy.
$ npx -y skills add majiayu000/spellbook --skill figma-to-react --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition โ
- You can call itInvoke it directly when you want it.
- Slash command
/figma-to-react
Context preview
The summary Claude sees to decide when to auto-load this skill.
Use when the user wants to extract Figma designs into production-ready React or Next.js components with TypeScript, Tailwind CSS, and pixel-perfect accuracy.
SKILL.md
figma-to-react.SKILL.mdname: figma-to-react
description: Use when the user wants to extract Figma designs into production-ready React or Next.js components with TypeScript, Tailwind CSS, and pixel-perfect accuracy.
Figma to React - Production-Ready Component Generator
๐ฏ Purpose
Extract **complete, lossless** design information from Figma and generate production-ready React/Next.js components with TypeScript and Tailwind CSS.
---
๐จ CRITICAL RULES - Read First!
**Rule 1: NEVER Truncate Code**
Use **100% of Figma MCP output**. Every className, every property matters.
// โ
CORRECT: Keep ALL className from Figma MCP
<div className="absolute font-source-serif h-[108px] leading-[1.8] left-[100px] not-italic text-[20px] text-[rgba(29,38,45,0.8)] text-justify top-[210px] w-[1096px] whitespace-pre-wrap">
// โ WRONG: Removing any className
<div className="absolute left-[100px] top-[210px] font-source-serif text-[20px]">
**Rule 2: Flatten `absolute contents` Structures**
**๐ฅ CRITICAL: Figma MCP returns nested `absolute contents` containers. `display: contents` makes the parent "disappear" - children are positioned relative to the nearest positioned ancestor (root)!**
**Key Insight: Children's positions are ALREADY absolute - DO NOT add parent's top/left!**
// โ WRONG: Figma MCP output (has redundant parent wrapper)
<div className="absolute contents left-0 top-[41px]">
<p className="absolute left-[100px] top-[41px]">TITLE</p>
<div className="absolute left-0 top-[100px]">Line</div>
</div>
// โ
CORRECT: Just remove the parent wrapper, keep children's positions AS-IS
<>
<p className="absolute left-[100px] top-[41px]">TITLE</p>
<div className="absolute left-0 top-[100px] w-[1920px] h-[1px] bg-[#C5CBCE] opacity-30" />
</>
**Position Handling Rules:**
| Parent Type | Child Position | Action | |-------------|----------------|--------| | `absolute contents` | Child has own `top/left` | **Keep child position AS-IS**, just remove parent | | `absolute` (no contents) | Child has relative `top/left` | Calculate: `parent + child` | | `relative` | Child has `top/left` | Calculate: `parent + child` |
**๐ฅ The Golden Rule:**
If parent has "contents" class โ Child positions are already absolute โ Keep AS-IS
If parent has NO "contents" class โ Child positions are relative โ Add parent + child
**Reference: Verified correct positions (from production HTML):**
- Header text: `top-[41px]` (not 82px)
- Header line: `top-[100px]` (not 141px)
- Footer line: `top-[980px]`
- Page number: `top-[1004px]`
**Rule 3: Extract Dimensions from Metadata**
**NEVER hardcode dimensions!**
// 1. Get metadata first
const metadata = await mcp__figma__get_metadata({
fileKey: 'xxx',
nodeId: '11:1420'
})
// 2. Extract from XML
// <frame width="1920" height="1080">
const pageWidth = 1920
const pageHeight = 1080
// 3. Use extracted values
<div className="w-[1920px] h-[1080px]">**Rule 4: Font Loading & Name Mapping**
**๐ฅ CRITICAL: Use Google Fonts CDN directly, NOT `next/font/google`!**
`next/font/google` generates CSS variables and self-hosts fonts, but the font rendering may differ from reference HTML that uses Google Fonts CDN directly. This causes:
- Different character widths (text wrapping issues)
- Different optical size handling for variable fonts
**4.1 Font Loading (layout.tsx)**
// โ WRONG: Using next/font/google
import { Source_Serif_4, Kaisei_Tokumin } from 'next/font/google'
const sourceSerif = Source_Serif_4({ subsets: ['latin'], variable: '--font-source-serif' })
// This may render fonts differently than Google Fonts CDN!
// โ
CORRECT: Use Google Fonts CDN directly in layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
<link
href="https://fonts.googleapis.com/css2?family=Source+Serif+4:ital,opsz,wght@0,8..60,200..900;1,8..60,200..900&family=Kaisei+Tokumin:wght@400;500;700;800&display=swap"
rel="stylesheet"
/>
</head>
<body>{children}</body>
</html>
)
}**Key:** Include `opsz` (optical size) axis for Source Serif 4 - this affects character widths!
**4.2 Font CSS (globals.css)**
@layer utilities {
/* Use direct font-family names, NOT CSS variables */
.font-source-serif {
font-family: 'Source Serif 4', serif;
}
.font-kaisei {
font-family: 'Kaisei Tokumin', serif;
}
}**4.3 Font Name Mapping**
// Figma MCP returns:
font-['Kaisei_Tokumin:ExtraBold',sans-serif]
font-['Source_Serif_Pro:SemiBold',sans-serif]
// โ
Convert to Tailwind classes:
font-kaisei font-extrabold
font-source-serif font-semibold
// Font name corrections (Google Fonts 2024):
'Source Serif Pro' โ 'Source Serif 4'
'Source Sans Pro' โ 'Source Sans 3'
**4.4 Font Weight Mismatch Warning**
**โ ๏ธ Figma's font weight names may NOT match CSS font-weights!**
Figma renders fonts differently than browsers. What Figma calls "Bold" might visually appear lighter than CSS `font-weight: 700`.
| Figma Weight Name | Expected CSS | May Actually Need | |-------------------|--------------|-------------------| | Regular | 400 | 400 | | Medium | 500 | 500 | | Bold | 700 | **500 or 600** (test visually!) | | ExtraBold | 800 | **700** (test visually!) |
**Solution:** Always compare with Figma screenshot. If text looks too bold, try one weight lighter:
- `font-bold` (700) โ try `font-medium` (500)
- `font-extrabold` (800) โ try `font-bold` (700)
**Rule 5: Critical CSS**
**Must add to globals.css:**
body {
overflow-x: auto; /* Allow horizontal scroll */
}
.page-container {
min-width: max-content; /* Prevent compression */
display: inline-block; /* Keep layout intact */
}**Rule 6: Re
Read more
name: figma-to-react description: Use when the user wants to extract Figma designs into production-ready React or Next.js components with TypeScript, Tailwind CSS, and pixel-perfect accuracy.
Figma to React - Production-Ready Component Generator
๐ฏ Purpose
Extract **complete, lossless** design information from Figma and generate production-ready React/Next.js components with TypeScript and Tailwind CSS.
---
๐จ CRITICAL RULES - Read First!
**Rule 1: NEVER Truncate Code**
Use **100% of Figma MCP output**. Every className, every property matters.
// โ CORRECT: Keep ALL className from Figma MCP <div className="absolute font-source-serif h-[108px] leading-[1.8] left-[100px] not-italic text-[20px] text-[rgba(29,38,45,0.8)] text-justify top-[210px] w-[1096px] whitespace-pre-wrap"> // โ WRONG: Removing any className <div className="absolute left-[100px] top-[210px] font-source-serif text-[20px]">
**Rule 2: Flatten `absolute contents` Structures**
**๐ฅ CRITICAL: Figma MCP returns nested `absolute contents` containers. `display: contents` makes the parent "disappear" - children are positioned relative to the nearest positioned ancestor (root)!**
**Key Insight: Children's positions are ALREADY absolute - DO NOT add parent's top/left!**
// โ WRONG: Figma MCP output (has redundant parent wrapper) <div className="absolute contents left-0 top-[41px]"> <p className="absolute left-[100px] top-[41px]">TITLE</p> <div className="absolute left-0 top-[100px]">Line</div> </div> // โ CORRECT: Just remove the parent wrapper, keep children's positions AS-IS <> <p className="absolute left-[100px] top-[41px]">TITLE</p> <div className="absolute left-0 top-[100px] w-[1920px] h-[1px] bg-[#C5CBCE] opacity-30" /> </>
**Position Handling Rules:**
| Parent Type | Child Position | Action | |-------------|----------------|--------| | `absolute contents` | Child has own `top/left` | **Keep child position AS-IS**, just remove parent | | `absolute` (no contents) | Child has relative `top/left` | Calculate: `parent + child` | | `relative` | Child has `top/left` | Calculate: `parent + child` |
**๐ฅ The Golden Rule:**
If parent has "contents" class โ Child positions are already absolute โ Keep AS-IS If parent has NO "contents" class โ Child positions are relative โ Add parent + child
**Reference: Verified correct positions (from production HTML):**
- Header text: `top-[41px]` (not 82px)
- Header line: `top-[100px]` (not 141px)
- Footer line: `top-[980px]`
- Page number: `top-[1004px]`
**Rule 3: Extract Dimensions from Metadata**
**NEVER hardcode dimensions!**
// 1. Get metadata first
const metadata = await mcp__figma__get_metadata({
fileKey: 'xxx',
nodeId: '11:1420'
})
// 2. Extract from XML
// <frame width="1920" height="1080">
const pageWidth = 1920
const pageHeight = 1080
// 3. Use extracted values
<div className="w-[1920px] h-[1080px]">**Rule 4: Font Loading & Name Mapping**
**๐ฅ CRITICAL: Use Google Fonts CDN directly, NOT `next/font/google`!**
`next/font/google` generates CSS variables and self-hosts fonts, but the font rendering may differ from reference HTML that uses Google Fonts CDN directly. This causes:
- Different character widths (text wrapping issues)
- Different optical size handling for variable fonts
**4.1 Font Loading (layout.tsx)**
// โ WRONG: Using next/font/google
import { Source_Serif_4, Kaisei_Tokumin } from 'next/font/google'
const sourceSerif = Source_Serif_4({ subsets: ['latin'], variable: '--font-source-serif' })
// This may render fonts differently than Google Fonts CDN!
// โ
CORRECT: Use Google Fonts CDN directly in layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
<link
href="https://fonts.googleapis.com/css2?family=Source+Serif+4:ital,opsz,wght@0,8..60,200..900;1,8..60,200..900&family=Kaisei+Tokumin:wght@400;500;700;800&display=swap"
rel="stylesheet"
/>
</head>
<body>{children}</body>
</html>
)
}**Key:** Include `opsz` (optical size) axis for Source Serif 4 - this affects character widths!
**4.2 Font CSS (globals.css)**
@layer utilities {
/* Use direct font-family names, NOT CSS variables */
.font-source-serif {
font-family: 'Source Serif 4', serif;
}
.font-kaisei {
font-family: 'Kaisei Tokumin', serif;
}
}**4.3 Font Name Mapping**
// Figma MCP returns: font-['Kaisei_Tokumin:ExtraBold',sans-serif] font-['Source_Serif_Pro:SemiBold',sans-serif] // โ Convert to Tailwind classes: font-kaisei font-extrabold font-source-serif font-semibold // Font name corrections (Google Fonts 2024): 'Source Serif Pro' โ 'Source Serif 4' 'Source Sans Pro' โ 'Source Sans 3'
**4.4 Font Weight Mismatch Warning**
**โ ๏ธ Figma's font weight names may NOT match CSS font-weights!**
Figma renders fonts differently than browsers. What Figma calls "Bold" might visually appear lighter than CSS `font-weight: 700`.
| Figma Weight Name | Expected CSS | May Actually Need | |-------------------|--------------|-------------------| | Regular | 400 | 400 | | Medium | 500 | 500 | | Bold | 700 | **500 or 600** (test visually!) | | ExtraBold | 800 | **700** (test visually!) |
**Solution:** Always compare with Figma screenshot. If text looks too bold, try one weight lighter:
- `font-bold` (700) โ try `font-medium` (500)
- `font-extrabold` (800) โ try `font-bold` (700)
**Rule 5: Critical CSS**
**Must add to globals.css:**
body {
overflow-x: auto; /* Allow horizontal scroll */
}
.page-container {
min-width: max-content; /* Prevent compression */
display: inline-block; /* Keep layout intact */
}**Rule 6: Re
Cross-runtime skills for Claude Code, Codex, and multi-agent workflows.
Repo: majiayu000/spellbook
Other skills on spellbook.
- /agentsmd-optimize
Audit AND optimize a CLAUDE.md / AGENTS.md instruction file โ score it against the five high-leverage patterns, flag anti-patterns, then apply approved fixes in place. Use when the user says ไผๅ CLAUDE.md / ไผๅ AGENTS.md / optimize my agent doc / ๅธฎๆๆน claudemd, or after an audit
Open skill - /agentsmd-scaffold
Generate or update repository-specific AGENTS.md instruction files from real repo evidence. Use when asked to create, design, scaffold, split, or improve root or scoped AGENTS.md files for Codex/Claude/agent workflows, especially when a repo needs directory-specific rules,
Open skill - /api-design
REST/GraphQL/gRPC API design best practices. Use when designing APIs, defining contracts, handling versioning. Covers OpenAPI 3.2, GraphQL Federation, gRPC streaming.
Open skill - /app-ui-design
Mobile app UI design expert for iOS and Android. Use when designing app interfaces, creating design systems, ensuring accessibility, or following platform guidelines. Covers Material Design 3, Human Interface Guidelines, color theory, typography, and 2025 trends.
Open skill - /app-user-story-qa
End-to-end app feature inventory and user-story testing workflow with a canonical tracker. Use when the user asks to audit every feature, derive expected behavior from code, test user journeys, or explicitly fix and retest documented UX or logistical defects.
Open skill - /architecture-foundation
Design architecture foundations before implementation. Use when asked to design or refactor architecture, choose Rust/Go crate, package, module, runtime, workflow, or service boundaries, compare mature project architecture, prevent stacked one-off PRs, audit migration debt in
Open skill

