Skip to content
Development
Skill

/figma-to-code

Extract Figma designs and generate production-ready React/Next.js components with TypeScript, Tailwind CSS, and pixel-perfect accuracy. Use when a user provides a Figma URL or asks to convert Figma designs to code.

From plugin
spellbook
25893 skills10 agents
Install
$ npx -y skills add majiayu000/spellbook --skill figma-to-code --agent claude-code

How 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-code

Context preview

The summary Claude sees to decide when to auto-load this skill.

Extract Figma designs and generate production-ready React/Next.js components with TypeScript, Tailwind CSS, and pixel-perfect accuracy. Use when a user provides a Figma URL or asks to convert Figma designs to code.

SKILL.md

figma-to-code.SKILL.md
name: figma-to-code
description: Extract Figma designs and generate production-ready React/Next.js components with TypeScript, Tailwind CSS, and pixel-perfect accuracy. Use when a user provides a Figma URL or asks to convert Figma designs to code.

Figma to Code - 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-bl
Read more
Ships withspellbook

Cross-runtime skills for Claude Code, Codex, and multi-agent workflows.

Get the whole plugin

Other skills on spellbook.