Claude-code-plugins-plus figma-local-dev-loop
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/figma-pack/skills/figma-local-dev-loop" ~/.claude/skills/jeremylongshore-claude-code-plugins-plus-figma-local-dev-loop && rm -rf "$T"
manifest:
plugins/saas-packs/figma-pack/skills/figma-local-dev-loop/SKILL.mdsource content
Figma Local Dev Loop
Overview
Set up fast local development for two workflows: building Figma plugins that run inside the Figma editor, and building external apps that consume the Figma REST API.
Prerequisites
- Node.js 18+ with npm/pnpm
configured (seeFIGMA_PAT
)figma-install-auth- Figma desktop app (for plugin development)
Instructions
Step 1: REST API Project Structure
figma-integration/ ├── src/ │ ├── figma-client.ts # Shared fetch wrapper │ ├── extract-tokens.ts # Design token extraction │ └── export-assets.ts # Asset export pipeline ├── tests/ │ ├── figma-client.test.ts │ └── fixtures/ # Saved API responses for offline testing │ └── sample-file.json ├── .env.local # FIGMA_PAT, FIGMA_FILE_KEY (git-ignored) ├── .env.example # Template for team ├── tsconfig.json └── package.json
Step 2: Figma Plugin Project Structure
my-figma-plugin/ ├── manifest.json # Plugin manifest (required by Figma) ├── code.ts # Plugin backend (runs in sandbox) ├── ui.html # Plugin UI (runs in iframe) ├── package.json └── tsconfig.json
manifest.json (required):
{ "name": "My Plugin", "id": "1234567890", "api": "1.0.0", "main": "dist/code.js", "ui": "dist/ui.html", "editorType": ["figma"], "permissions": ["currentuser"] }
Step 3: Plugin Development with Watch Mode
{ "scripts": { "build": "esbuild code.ts --bundle --outfile=dist/code.js --target=es2020", "watch": "esbuild code.ts --bundle --outfile=dist/code.js --target=es2020 --watch", "dev": "concurrently \"npm run watch\" \"npm run watch:ui\"", "watch:ui": "esbuild ui.tsx --bundle --outfile=dist/ui.html --loader:.html=copy --watch" }, "devDependencies": { "@figma/plugin-typings": "^1.0.0", "esbuild": "^0.20.0", "typescript": "^5.0.0" } }
Load the plugin in Figma:
- Figma desktop > Plugins > Development > Import plugin from manifest
- Select your
manifest.json - Run with
-- changes auto-reloadnpm run watch
Step 4: REST API Dev Loop with Testing
{ "scripts": { "dev": "tsx watch src/extract-tokens.ts", "test": "vitest", "test:watch": "vitest --watch" } }
// tests/figma-client.test.ts import { describe, it, expect, vi, beforeEach } from 'vitest'; import { readFileSync } from 'fs'; // Load a saved API response for offline testing const sampleFile = JSON.parse( readFileSync('tests/fixtures/sample-file.json', 'utf-8') ); describe('Figma token extraction', () => { beforeEach(() => { // Mock fetch to return saved fixture vi.spyOn(global, 'fetch').mockResolvedValue( new Response(JSON.stringify(sampleFile), { status: 200 }) ); }); it('should extract color styles from file', async () => { const res = await fetch('https://api.figma.com/v1/files/test-key'); const file = await res.json(); const styles = Object.values(file.styles); expect(styles.length).toBeGreaterThan(0); }); });
Step 5: Save API Fixtures for Offline Dev
# Snapshot a Figma file for offline testing curl -s -H "X-Figma-Token: ${FIGMA_PAT}" \ "https://api.figma.com/v1/files/${FIGMA_FILE_KEY}" \ > tests/fixtures/sample-file.json # Snapshot specific nodes curl -s -H "X-Figma-Token: ${FIGMA_PAT}" \ "https://api.figma.com/v1/files/${FIGMA_FILE_KEY}/nodes?ids=0:1,0:2" \ > tests/fixtures/sample-nodes.json
Output
- Working dev environment with hot reload
- Test suite with mocked Figma API responses
- Saved fixtures for offline development
- Plugin manifest configured for Figma desktop loading
Error Handling
| Error | Cause | Solution |
|---|---|---|
| Plugin not appearing in Figma | Wrong manifest path | Re-import from correct |
global undefined | Running outside Figma sandbox | Use for types only |
| Fixture stale | File changed since snapshot | Re-run fixture download script |
| esbuild watch crash | Syntax error in TS | Fix error; watch auto-restarts |
Examples
Quick Plugin Skeleton
// code.ts -- minimal Figma plugin figma.showUI(__html__, { width: 300, height: 200 }); figma.ui.onmessage = (msg: { type: string; count: number }) => { if (msg.type === 'create-rectangles') { for (let i = 0; i < msg.count; i++) { const rect = figma.createRectangle(); rect.x = i * 150; rect.fills = [{ type: 'SOLID', color: { r: 1, g: 0.5, b: 0 } }]; figma.currentPage.appendChild(rect); } figma.closePlugin(); } };
Resources
Next Steps
See
figma-sdk-patterns for production-ready code patterns.