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で見る