Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Set up iterative design-to-code development loop with Anima SDK. Use when rapidly iterating on Figma-to-code output, comparing framework outputs, or building a local preview server for generated components. Trigger: "anima local dev", "anima dev loop", "anima preview", "anima iteration".
.claude/skills/jeremylongshore-anima-local-dev-loop/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-19 | ✗→✓ | ▲ Improved | -8% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 25% | 0% |
| case-02 | ✗→✓ | ▲ Improved | -1% | 0% |
| case-04 | ✗→✓ | ▲ Improved | -8% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 4% | 0% |
Iterate on one approved Figma node with supported React or HTML settings. Preserve the source revision and settings for each run, preview locally, and accept a result only after deterministic code and visual checks.
from an ignored local environment file or development secret store.
production application until code and visual review pass.
behavior, dependencies, and generation settings.
bashmkdir anima-dev && cd anima-dev npm init -y npm install @animaapp/anima-sdk dotenv npm install -D vite @vitejs/plugin-react typescript
typescript// scripts/generate-preview.ts import { Anima } from '@animaapp/anima-sdk'; import fs from 'fs'; import path from 'path'; import 'dotenv/config'; const anima = new Anima({ auth: { token: process.env.ANIMA_TOKEN! } }); const SETTINGS_PRESETS = { 'react-tailwind': { language: 'typescript' as const, framework: 'react' as const, styling: 'tailwind' as const }, 'react-shadcn': { language: 'typescript' as const, framework: 'react' as const, styling: 'tailwind' as const, uiLibrary: 'shadcn' as const }, 'react-plain-css': { language: 'typescript' as const, framework: 'react' as const, styling: 'plain_css' as const }, 'html-plain-css': { language: 'javascript' as const, framework: 'html' as const, styling: 'plain_css' as const }, }; async function generateWithPreset(preset: keyof typeof SETTINGS_PRESETS, nodeId: string) { const settings = SETTINGS_PRESETS[preset]; const outputDir = `./generated/${preset}`; fs.mkdirSync(outputDir, { recursive: true }); const { files } = await anima.generateCode({ fileKey: process.env.FIGMA_FILE_KEY!, figmaToken: process.env.FIGMA_TOKEN!, nodesId: [nodeId], settings, }); for (const [fileName, file] of Object.entries(files)) { if (file.isBinary) throw new Error(`Handle binary output separately: ${fileName}`); const root = path.resolve(outputDir); const target = path.resolve(root, fileName); if (!target.startsWith(`${root}${path.sep}`)) throw new Error('Unsafe output path'); fs.mkdirSync(path.dirname(target), { recursive: true }); fs.writeFileSync(target, file.content); } console.log(`${preset}: ${Object.keys(files).length} files generated`); } // Compare all presets async function compareOutputs(nodeId: string) { for (const preset of Object.keys(SETTINGS_PRESETS) as Array<keyof typeof SETTINGS_PRESETS>) { await generateWithPreset(preset, nodeId); // Stop on provider/Figma rate limits; apply the bounded rate-limit workflow. } console.log('\nAll presets generated in ./generated/'); } const nodeId = process.argv[2] || '1:2'; compareOutputs(nodeId).catch(() => { console.error({ failureClass: 'preview-generation-failed' }); process.exitCode = 1; });
json{ "scripts": { "generate": "tsx scripts/generate-preview.ts", "generate:node": "tsx scripts/generate-preview.ts", "preview": "vite", "dev": "npm run generate && npm run preview" } }
Use Read and Grep to inspect the existing integration and generated diff before changing anything. Use Write or Edit only inside the approved generated-code, test, or configuration paths. Use the declared Bash commands only for the explicit install, validation, or diagnostic steps in this workflow; never print tokens, source designs, generated source, or private website captures.
Select one approved staging frame and run only the react-tailwind preset first. Preview the result locally, compare it to the design for semantics and responsive behavior, and run the project formatter/type check before trying a second preset. Store the Figma version and preset alongside the generated review artifact so the comparison is repeatable. If generation hits a rate limit, output changes unexpectedly, or an unapproved dependency appears, stop the loop, preserve the sanitized error, and correct the fixture or settings instead of continuously regenerating.
| Error | Cause | Solution | |-------|-------|----------| | Rate limited | Too many generations | Add 2s delay between calls | | Different outputs each run | Anima AI variation | Pin settings; use consistent node IDs |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-19 | fail→pass | 7,444 | 2,434 | -67% | 1 | 1 | 0% | 1,456 | 1,337 | -8% | 0 | 0 | — |
case-01 | fail→pass | 15,218 | 13,456 | -12% | 1 | 1 | 0% | 3,253 | 4,074 | +25% | 0 | 0 | — |
case-02 | fail→pass | 15,764 | 10,452 | -34% | 1 | 1 | 0% | 3,485 | 3,437 | -1% | 0 | 0 | — |
case-03 | fail→fail | 46,192 | 20,941 | -55% | 1 | 1 | 0% | 5,796 | 5,776 | -0% | 0 | 0 | — |
case-04 | fail→pass | 9,647 | 5,012 | -48% | 1 | 1 | 0% | 2,038 | 1,877 | -8% | 0 | 0 | — |
case-05 | fail→pass | 7,685 | 3,299 | -57% | 1 | 1 | 0% | 1,475 | 1,528 | +4% | 0 | 0 | — |
case-06 | fail→pass | 5,907 | 3,413 | -42% | 1 | 1 | 0% | 978 | 1,590 | +63% | 0 | 0 | — |
case-07 | pass→pass | 4,121 | 2,532 | -39% | 1 | 1 | 0% | 818 | 1,378 | +68% | 0 | 0 | — |
case-08 | fail→pass | 4,652 | 2,200 | -53% | 1 | 1 | 0% | 895 | 1,253 | +40% | 0 | 0 | — |
case-09 | pass→pass | 11,101 | 2,106 | -81% | 1 | 1 | 0% | 1,869 | 1,200 | -36% | 0 | 0 | — |
case-10 | fail→pass | 9,382 | 3,461 | -63% | 1 | 1 | 0% | 1,702 | 1,523 | -11% | 0 | 0 | — |
case-11 | fail→pass | 9,404 | 2,119 | -77% | 1 | 1 | 0% | 1,887 | 1,351 | -28% | 0 | 0 | — |
case-12 | fail→pass | 12,693 | 4,366 | -66% | 1 | 1 | 0% | 2,316 | 1,783 | -23% | 0 | 0 | — |
case-13 | fail→pass | 5,661 | 3,149 | -44% | 1 | 1 | 0% | 1,048 | 1,472 | +40% | 0 | 0 | — |
case-14 | pass→pass | 6,878 | 4,069 | -41% | 1 | 1 | 0% | 1,422 | 1,659 | +17% | 0 | 0 | — |
case-15 | fail→pass | 7,959 | 1,921 | -76% | 1 | 1 | 0% | 1,548 | 1,192 | -23% | 0 | 0 | — |
case-16 | fail→pass | 6,580 | 1,885 | -71% | 1 | 1 | 0% | 1,201 | 1,141 | -5% | 0 | 0 | — |
case-17 | pass→pass | 14,349 | 11,664 | -19% | 1 | 1 | 0% | 2,437 | 2,971 | +22% | 0 | 0 | — |
case-18 | fail→pass | 6,474 | 4,259 | -34% | 1 | 1 | 0% | 1,222 | 1,706 | +40% | 0 | 0 | — |
case-20 | pass→pass | 13,908 | 12,038 | -13% | 1 | 1 | 0% | 2,912 | 3,622 | +24% | 0 | 0 | — |
case-21 | pass→pass | 13,712 | 14,859 | +8% | 1 | 1 | 0% | 3,034 | 3,930 | +30% | 0 | 0 | — |
case-22 | pass→pass | 7,713 | 6,632 | -14% | 1 | 1 | 0% | 1,723 | 2,267 | +32% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +64 percentage points is the difference between those two pass rates over the 22 comparable cases.
The publisher has shipped newer versions since this run, so these numbers describe v1, not the version currently listed.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.