AI Skill Report Card

Building Figma Plugins

B+78·Feb 26, 2026·Source: Web
15 / 15
TypeScript
// manifest.json { "name": "Brand Compliance Checker", "id": "brand-checker", "api": "1.0.0", "main": "code.js", "ui": "ui.html" } // code.ts figma.showUI(__html__, { width: 320, height: 240 }); figma.ui.onmessage = msg => { if (msg.type === 'check-brand-compliance') { const selection = figma.currentPage.selection; const violations = []; selection.forEach(node => { if (node.type === 'TEXT') { const fills = node.fills as Paint[]; if (!isApprovedBrandColor(fills[0])) { violations.push({ id: node.id, name: node.name, issue: 'Unapproved text color' }); } } }); figma.ui.postMessage({ type: 'violations', data: violations }); } };
Recommendation
Add specific error handling patterns with concrete examples of common Figma API errors and how to handle them
14 / 15

Progress:

  • Set up TypeScript environment (npm init, @figma/plugin-typings)
  • Define plugin manifest and core structure
  • Implement main functionality using Figma API
  • Build UI communication layer
  • Test with Figma Dev Mode
  • Package and publish to Community

1. Environment Setup

Bash
npm init -y npm install @figma/plugin-typings typescript npx tsc --init

2. Core API Patterns

TypeScript
// Node traversal function traverseNode(node: SceneNode, callback: (node: SceneNode) => void) { callback(node); if ('children' in node) { node.children.forEach(child => traverseNode(child, callback)); } } // Selection handling const selection = figma.currentPage.selection; if (selection.length === 0) { figma.notify('Please select elements first'); return; } // UI communication figma.ui.postMessage({ type: 'data', payload: results }); figma.ui.onmessage = msg => { switch (msg.type) { case 'apply-tokens': applyDesignTokens(msg.tokens); break; } };

3. High-Value Automations

Brand Compliance Checker:

TypeScript
const BRAND_COLORS = ['#FF6B35', '#004E89', '#FFFFFF']; const BRAND_FONTS = ['Inter', 'Roboto']; function checkCompliance(node: SceneNode) { const issues = []; if (node.type === 'TEXT') { if (!BRAND_FONTS.includes(node.fontName.family)) { issues.push('Non-brand font detected'); } } if ('fills' in node && node.fills !== figma.mixed) { const fills = node.fills as Paint[]; fills.forEach(fill => { if (fill.type === 'SOLID' && !isBrandColor(fill.color)) { issues.push('Unapproved color'); } }); } return issues; }

Design Token Applicator:

TypeScript
const TOKENS = { 'primary-500': { r: 1, g: 0.42, b: 0.21 }, 'spacing-lg': 24, 'radius-md': 8 }; function applyToken(node: SceneNode, tokenName: string) { if (tokenName.includes('color') && 'fills' in node) { node.fills = [{ type: 'SOLID', color: TOKENS[tokenName] }]; } else if (tokenName.includes('spacing') && 'paddingLeft' in node) { const spacing = TOKENS[tokenName]; node.paddingLeft = node.paddingRight = spacing; node.paddingTop = node.paddingBottom = spacing; } }

4. Component Analysis

TypeScript
function exportComponentInventory() { const components = []; traverseNode(figma.root, node => { if (node.type === 'INSTANCE') { components.push({ name: node.mainComponent?.name, id: node.id, page: node.parent?.name, overrides: getOverrides(node) }); } }); return components; }
Recommendation
Include a complete HTML UI example to complement the TypeScript code snippets
16 / 20

Example 1: SEO Alt-Text Generator Input: Selected images without alt text Output:

TypeScript
// Generates descriptive alt text for selected images selection.forEach(node => { if (node.type === 'RECTANGLE' && node.fills) { const altText = generateAltText(node); node.setPluginData('alt-text', altText); figma.notify(`Added alt text: "${altText}"`); } });

Example 2: Brand Color Enforcement Input: Design with mixed colors Output: Automatically replaces non-brand colors with nearest brand-approved alternatives

Recommendation
Add more concrete input/output pairs showing actual node properties and transformations
  • Batch operations: Process multiple selections efficiently
  • Progress feedback: Use figma.notify() for user feedback
  • Error handling: Wrap API calls in try-catch blocks
  • Memory management: Clone nodes before major modifications
  • Plugin data: Store metadata using setPluginData() for persistence
  • TypeScript strict mode: Catch API misuse early
  • Don't modify nodes during traversal (clone first)
  • Don't forget to handle mixed properties (figma.mixed)
  • Don't assume selection exists (always check length)
  • Don't block UI thread with heavy operations (use async/await)
  • Don't forget manifest permissions for network requests
  • Don't hardcode dimensions (use figma.viewport for responsive UI)
TypeScript
// Debug helper console.log(JSON.stringify(node, null, 2)); // Performance monitoring console.time('plugin-operation'); // ... your code console.timeEnd('plugin-operation');

Use Figma Dev Mode → Plugins → Development for testing. Publish through Figma Community with clear screenshots and usage instructions.

0
Grade B+AI Skill Framework
Scorecard
Criteria Breakdown
Quick Start
15/15
Workflow
14/15
Examples
16/20
Completeness
17/20
Format
14/15
Conciseness
12/15