Fix your Figma file before AI writes the code

HandOffLint reviews your design for layout and structure problems before you hand it off to tools like Cursor, v0, or Claude. Catch messy frames early so the code you get back is clean, responsive, and ready to ship—not a pile of fixes.

Messy designs become messy code

AI coding tools can only work with what they see. When a Figma file is disorganized, the output is hard to maintain.

Designers move fast in Figma—and that speed often leaves problems behind: layers stacked on top of each other, frames without proper containers, elements placed with fixed pixel positions, and half-finished layers buried in the file.

When you ask an AI tool to turn that file into code, it reads the pixels and layer tree as-is. Without clear structure—things like Auto Layout, consistent spacing, and named components—it guesses. Often it copies exact x/y coordinates into your CSS.

The result is brittle code: fixed-position divs that break on different screen sizes, skip accessibility basics, and ignore your design system. Developers then spend hours rewriting what should have been a straightforward handoff.

Bad input, bad outputSkipping a design check before generation means fixing layout and structure in code instead of fixing them once in Figma— where it takes minutes, not days.
Brittle Layout Generation OutputUnguided
/* absolute coordinates generated by LLM */
<div className="absolute top-[142px] left-[24px] w-[280px] h-[48px] bg-indigo-600 rounded">
  <span className="absolute top-[10px] left-[16px]">
    Submit Action
  </span>
</div>
Without clear layout rules in the design, the AI falls back to fixed coordinates—and the UI falls apart on mobile or resize.

System Architecture Flow

The multi-staged pipeline designed to process Figma inputs into structured prompt injections.

01

Ingestion & Server Caching

The pipeline extracts the fileKey and target nodeId. Rather than re-fetching deeply nested trees across subsequent requests, it flattens nodes into Upstash Redis for O(1) property lookup across wizard steps and serverless instances.

02

Deterministic Analysis

Executes 8 structural TypeScript audits to test spacing alignments, contrast calculations, and Auto Layout bounds. Computes a quantitative design Readiness Score scaled on layout density profiles.

03

ReAct Vision Loop

A multi-step visual agent inspects the frame image. It executes zero-cost local tools to query cached properties and performs paragraph-chunk keyword RAG checks against GitHub guideline documents. Walkthrough →

POST URL
POST Profile
POST Image
Display
Fetch Tree
Save
Start Loop
Stream JSON
Lookup Props
Fetch Markdown
User
Wizard Dashboard
STEP 1

1. Input Figma URL

STEP 2

2. Select Profile

STEP 3

3. Launch Vision

STEP 4

4. View Results

Wizard state machine
Backend API
POST

/api/agent/init

Parses Figma URL, saves mapped tree flat.

POST

/api/agent/audit

runNaming
runLayout
runHidden
runSpacing
runContrast
runSvg
runExport
runReuse
POST

/api/agent/vision

Executes streaming multi-turn loop.

→ guardrails→ evals

Flat IndexRedis (Upstash)
O(1) Props
External

Figma API

Subtree fetcher

GitHub Raw

Style guideline markdown

Offline measurement

Vision Agent Evaluations

A proof-of-concept golden dataset — three mobile-app frames — measures how reliably the ReAct vision agent finds cross-modal defects today. Runs are captured once, human-reviewed, then replayed offline in CI. This is an honesty check on model behavior, not a claim that the vision agent is production-ready at scale.

Golden cases
3

vaxin ×2, Bittersweet modal

Runs per case
10

Same frame, repeated to surface variance

Overall pass rate
77%

Mixed — strong on simple frames, weaker on complex modals

Each case pairs a Figma node tree with a rendered frame image. The capture workflow seeds the flat index, runs the vision agent ten times, applies cross-modal guardrails, and commits JSON results under evals/results/. Vitest replays those committed outputs — no live Gemini in CI.

What the numbers do not mean

These evals validate the measurement pipeline and show where the agent is already useful (clear typos, obvious hierarchy clashes). They do not mean the vision model is consistent enough for unattended production use across arbitrary Figma files.

Known limitations today

  • Only 3 golden cases and one layout profile (mobile-app) — not representative of all handoff scenarios.
  • Gemini output is non-deterministic: the Order Details Modal case reaches just 40% full-match across 10 runs, even when individual findings appear more often.
  • Large or layered frames are harder — the model sometimes catches layout issues but misses subtle cross-modal text mismatches, or vice versa.
  • Capture was constrained by API quota; failed runs are excluded from pass-rate math, which can overstate stability on thin successful-run samples.

Improvements needed before scale

  • Expand the golden set — more frames, layout profiles, and defect types.
  • Run consensus voting (e.g. require a finding in ≥6/10 runs) before surfacing it.
  • Decompose large frames into regions instead of one full-frame vision pass.
  • Add per-finding confidence scores and explicit “needs human review” states.
  • Tighten guardrails and recalibrate when the model or prompt changes.
View full eval showcase

Locked case pass rates

Google Pixel 2 - 1

vaxin-1-4

100%

Google Pixel 2 - 4

vaxin-20-0

90%

Order Details Modal

bittersweet-9-153

40%

Pass rate = share of successful runs that matched all locked expected findings. High scores on simple frames and lower scores on complex modals are both useful signals — they show where the agent is ready to assist and where human review is still required.

Deterministic Linter Rules

The 8 automated TypeScript rules used to inspect raw properties before agent execution.

Rule 01Naming Conventions

Flags generic names such as "Rectangle 211". Establishes structured naming constraints.

Rule 02Layout Constraints

Verifies structural auto-layout configurations to substitute coordinate maps with box models.

Rule 03Hidden Cruft

Strips stray, disabled draft groups so they do not bloat downstream LLM context payloads.

Rule 04Spacing Variables

Validates padding, margin, and alignment coordinates against 4px and 8px grid tolerances.

Rule 05WCAG Contrast

Computes relative luminance of absolute visual text nodes to satisfy accessibility grades.

Rule 06SVG Structure

Validates height, width, and viewport dimensions inside vector shapes to prevent scaling clips.

Rule 07Assets Export

Monitors component export profiles to trigger warnings on missing static resources early.

Rule 08Component Reuse

Matches nodes to external instance libraries to direct AI toward pre-built systems.

Project Architecture Specifications

The tech-stack elements compiled for this Capstone implementation.

Next.js App Router Framework

Utilizes server actions and modular API router boundaries. The application orchestrates processes across three logical routes: /api/agent/init, /api/agent/audit, and /api/agent/vision.

Vercel AI SDK & Gemini 2.5 Flash

Drives multi-turn visual agent tool actions via structured system models. The agent uses image analysis alongside local utility executions. Outputs are generated to fulfill strict Zod parsing schema expectations.

Redis Flat Index

Persists flattened Figma node maps in Upstash Redis (figma:flat:fileKey) so init, audit, and vision routes share state across serverless invocations. Falls back to in-process memory when Redis credentials are unset.

Keyword Chunk-Matching RAG

Decouples complicated database structures in favor of lightweight text manipulation. Splits downloaded markdown targets into paragraphs, maps overlaps against incoming user requests, and supplies context lists.