Skip to main content

figma-design-md-plugin

Figma plugin that extracts local styles and generates DESIGN.md and SKILL.md files for AI-driven design system implementation

설치로 이동

소스 정보

저장소
reason-machines/design-skills
최근 소스 활동
2026년 5월 17일 23:19
감지된 SKILL.md 언어
영어
스타
4
포크
0

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
figma-design-md-plugin
description
Figma plugin that extracts local styles and generates DESIGN.md and SKILL.md files for AI-driven design system implementation
triggers
["extract design tokens from Figma","generate DESIGN.md from Figma file","create design system documentation from Figma","build SKILL.md for AI coding agents","export Figma styles to markdown","convert Figma variables to design tokens","setup TypeUI design guidelines","auto-generate design system blueprint"]
# Figma Design.md Plugin Skill > Skill by [ara.so](https://ara.so) — Design Skills collection. ## Overview The **design-md-figma** plugin extracts local styles, variables, and component families from Figma files and generates standardized `DESIGN.md` and `SKILL.md` files. These outputs provide AI coding agents with design-system blueprints for building consistent interfaces. The plugin reads: - Local color/typography/spacing/radius/motion styles - Figma variable collections - Effect styles (shadows, blur) - Grid styles - Component families It generates TypeUI-format markdown that AI agents can use to implement design-consistent code. ## Installation & Setup ### Development Setup ```bash # Clone the repository git clone https://github.com/bergside/design-md-figma.git cd design-md-figma # Install dependencies npm install # Build the plugin npm run build ``` ### Load in Figma Desktop 1. Open Figma Desktop 2. Navigate to **Plugins → Development → Import plugin from manifest...** 3. Select the `manifest.json` file from your cloned directory 4. The plugin appears in **Plugins → Development → Design MD Skill Generator** ### Watch Mode for Development ```bash # Auto-rebuild on file changes npm run watch ``` ## Plugin Architecture ### File Structure ``` design-md-figma/ ├── src/ │ ├── code.ts # Main plugin logic (runs in Figma sandbox) │ ├── ui.html # Plugin UI (runs in iframe) │ └── types.ts # TypeScript type definitions ├── manifest.json # Figma plugin configuration └── package.json ``` ### Key TypeScript Interfaces ```typescript interface ExtractedData { source: { fileName: string; pageNames: string[]; timestamp: string; }; variableCollections: VariableCollection[]; colorTokens: ColorToken[]; typographyTokens: TypographyToken[]; spacingTokens: SpacingToken[]; radiusTokens: RadiusToken[]; effectStyles: EffectStyle[]; gridStyles: GridStyle[]; componentFamilies: string[]; } interface ColorToken { name: string; value: string; // hex, rgb(), or variable reference type: 'paint-style' | 'color-variable'; } interface TypographyToken { name: string; fontFamily: string; fontSize: number; fontWeight: number; lineHeight: string; letterSpacing: string; } ``` ## Core Plugin Functions ### Extracting Design Tokens The plugin automatically extracts tokens when run: ```typescript // Main extraction flow (src/code.ts) async function extractDesignTokens(): Promise<ExtractedData> { const data: ExtractedData = { source: { fileName: figma.root.name, pageNames: figma.root.children.map(page => page.name), timestamp: new Date().toISOString() }, variableCollections: [], colorTokens: [], typographyTokens: [], spacingTokens: [], radiusTokens: [], effectStyles: [], gridStyles: [], componentFamilies: [] }; // Extract local paint styles const paintStyles = figma.getLocalPaintStyles(); paintStyles.forEach(style => { const paint = style.paints[0]; if (paint.type === 'SOLID') { data.colorTokens.push({ name: style.name, value: rgbToHex(paint.color), type: 'paint-style' }); } }); // Extract local text styles const textStyles = figma.getLocalTextStyles(); textStyles.forEach(style => { data.typographyTokens.push({ name: style.name, fontFamily: style.fontName.family, fontSize: style.fontSize, fontWeight: style.fontName.style, lineHeight: formatLineHeight(style.lineHeight), letterSpacing: formatLetterSpacing(style.letterSpacing) }); }); // Extract variable collections const collections = figma.variables.getLocalVariableCollections(); collections.forEach(collection => { data.variableCollections.push({ id: collection.id, name: collection.name, modes: collection.modes.map(m => m.name) }); }); return data; } ``` ### Generating DESIGN.md ```typescript function generateDesignMD(data: ExtractedData): string { let markdown = `# DESIGN.md\n\n`; markdown += `## Source\n\n`; markdown += `- **File**: ${data.source.fileName}\n`; markdown += `- **Pages**: ${data.source.pageNames.join(', ')}\n`; markdown += `- **Extracted**: ${data.source.timestamp}\n\n`; markdown += `## Color Tokens\n\n`; markdown += `| Name | Value | Type |\n`; markdown += `| --- | --- | --- |\n`; data.colorTokens.forEach(token => { markdown += `| ${token.name} | ${token.value} | ${token.type} |\n`; }); markdown += `\n`; markdown += `## Typography Tokens\n\n`; markdown += `| Name | Family | Size | Weight | Line Height | Letter Spacing |\n`; markdown += `| --- | --- | --- | --- | --- | --- |\n`; data.typographyTokens.forEach(token => { markdown += `| ${token.name} | ${token.fontFamily} | ${token.fontSize}px | ${token.fontWeight} | ${token.lineHeight} | ${token.letterSpacing} |\n`; }); return markdown; } ``` ### Generating SKILL.md ```typescript function generateSkillMD(data: ExtractedData): string { let markdown = `# SKILL.md\n\n`; markdown += `## Mission\n\n`; markdown += `Build interfaces that strictly adhere to the design system extracted from **${data.source.fileName}**.\n\n`; markdown += `## Style Foundations\n\n`; markdown += `### Colors\n\n`; data.colorTokens.forEach(token => { markdown += `- **${token.name}**: \`${token.value}\`\n`; }); markdown += `\n`; markdown += `### Typography\n\n`; data.typographyTokens.forEach(token => { markdown += `- **${token.name}**: ${token.fontFamily} ${token.fontSize}px/${token.lineHeight}, weight ${token.fontWeight}\n`; }); markdown += `\n## Rules: Do\n\n`; markdown += `- Use extracted color tokens exactly as defined\n`; markdown += `- Apply typography scales from text styles\n`; markdown += `- Reference component families for consistency\n`; markdown += `- Follow spacing/radius token values\n\n`; markdown += `## Rules: Don't\n\n`; markdown += `- Never hardcode colors outside extracted palette\n`; markdown += `- Don't create arbitrary font sizes\n`; markdown += `- Avoid inconsistent spacing values\n`; return markdown; } ``` ## Message Passing (UI ↔ Plugin) The plugin uses Figma's message API: ```typescript // In code.ts (plugin sandbox) figma.ui.onmessage = async (msg) => { if (msg.type === 'extract') { const data = await extractDesignTokens(); figma.ui.postMessage({ type: 'extraction-complete', data }); } if (msg.type === 'generate-design-md') { const markdown = generateDesignMD(msg.data); figma.ui.postMessage({ type: 'markdown-ready', markdown, fileType: 'DESIGN.md' }); } }; // In ui.html (iframe) window.onmessage = (event) => { const msg = event.data.pluginMessage; if (msg.type === 'extraction-complete') { displayExtractedData(msg.data); } if (msg.type === 'markdown-ready') { updateEditor(msg.markdown); enableDownload(msg.markdown, msg.fileType); } }; ``` ## Common Usage Patterns ### Extract and Download DESIGN.md ```typescript // User opens plugin in Figma // Plugin auto-extracts on load figma.showUI(__html__, { width: 600, height: 800 }); const data = await extractDesignTokens(); figma.ui.postMessage({ type: 'extraction-complete', data }); // User clicks "Generate DESIGN.md" // UI sends message to plugin parent.postMessage({ pluginMessage: { type: 'generate-design-md', data } }, '*'); // Plugin generates markdown and sends back const markdown = generateDesignMD(data); figma.ui.postMessage({ type: 'markdown-ready', markdown, fileType: 'DESIGN.md' }); // UI enables download button function downloadFile(content: string, filename: string) { const blob = new Blob([content], { type: 'text/markdown' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; a.click(); } ``` ### Refresh Token Extraction ```typescript // User modifies Figma file (adds new color style) // User clicks "Refresh" in plugin UI parent.postMessage({ pluginMessage: { type: 'refresh' } }, '*'); // Plugin re-runs extraction const updatedData = await extractDesignTokens(); figma.ui.postMessage({ type: 'extraction-complete', data: updatedData }); ``` ### Toggle Between DESIGN.md and SKILL.md ```typescript // UI state management let currentView: 'design' | 'skill' = 'design'; function toggleView() { currentView = currentView === 'design' ? 'skill' : 'design'; parent.postMessage({ pluginMessage: { type: currentView === 'design' ? 'generate-design-md' : 'generate-skill-md', data: extractedData } }, '*'); } ``` ## Configuration ### manifest.json ```json { "name": "Design MD Skill Generator", "id": "1612814320994608244", "api": "1.0.0", "main": "dist/code.js", "ui": "dist/ui.html", "editorType": ["figma"], "networkAccess": { "allowedDomains": ["none"] } } ``` ### TypeScript Configuration ```json { "compilerOptions": { "target": "ES6", "module": "commonjs", "lib": ["ES2015"], "outDir": "./dist", "strict": true, "typeRoots": ["./node_modules/@types", "./node_modules/@figma"] } } ``` ## Helper Utilities ### Color Conversion ```typescript function rgbToHex(color: RGB): string { const r = Math.round(color.r * 255).toString(16).padStart(2, '0'); const g = Math.round(color.g * 255).toString(16).padStart(2, '0'); const b = Math.round(color.b * 255).toString(16).padStart(2, '0'); return `#${r}${g}${b}`; } function rgbaToString(color: RGBA): string { const r = Math.round(color.r * 255); const g = Math.round(color.g * 255); const b = Math.round(color.b * 255); return `rgba(${r}, ${g}, ${b}, ${color.a})`; }
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기