Skip to content

WF2Des โ€” How to Use

Summary

WF2Des turns a wireframe frame into a native Figma design, built from your project's own registered components and design tokens.
It does not draw new UI: it decides which registered component each part of the wireframe should become, keeps the wireframe's layout and copy, and assembles the result in your file.

Prerequisites

Everything happens inside the Figma plugin. Before generating anything:

1. Sign in

Sign in with your Plabs account. The plugin needs a project selected โ€” a design is always generated into a project's registry and rules.

2. Open the file that holds your design system

The components the generator picks from must live in the same Figma file as the wireframe. If a component cannot be found in the open file, it cannot be placed.

3. Have the boards ready

Two kinds of board are read during setup:

Board What it holds
Component boards The design system's component sets โ€” buttons, form fields, headers, cards
Guideline boards The written rules โ€” colours, typography, spacing, per-component usage

One-time setup

Open the Setup tab. Both steps read your canvas selection, so select the board frames first.

1. Component library

Select the component boards, then Review sync โ†’ Confirm sync.

The run reports four steps: Resolve โ†’ Sweep โ†’ Register โ†’ Save. It reads every component set on the selected boards and records its variants, text slots, sizes and publish keys.

Note

After the sync reports Completed, a second pass captures variant details directly from Figma. It walks every node on the selected boards, so on a large library it legitimately takes minutes โ€” the panel shows a live node count while it works. The sync result is already saved; the capture only enriches it.

Check it worked: open What's in the registry โ€” it lists what was registered, by board.

2. Design-rule boards

Select the guideline boards, then Review upload โ†’ Confirm upload.

The run reports Render โ†’ Extract โ†’ Merge โ†’ Save, and produces a new revision of the ruleset. Earlier revisions are kept: open Current rules & history to see colours, typography and spacing, and Revert to any previous revision.


Generating a design

Open the Generate tab.

  1. Select exactly one frame on the canvas โ€” the wireframe you want to convert. The plugin refuses a multi-selection or a non-frame node, and says which.
  2. Optionally set a Screen id. Leave it blank and one is derived from the frame name.
  3. Press Generate design.

The run reports four steps: Trigger โ†’ Parse โ†’ Assemble โ†’ Build. Parse and assemble happen on the server; build happens in your file. You can press Stop watching (run continues) at any point โ€” the run continues server-side and you can re-attach later.

When it finishes you get Total / Placed / Unmatched.


Reading the result

What you see What it means
Placed Built from a registered component, with the wireframe's own text placed into its slots
Unmatched Nothing in the registry fitted. Rendered as a dashed orange box so the gap is visible, never silently skipped
A dashed box where the wireframe had a picture Should not happen โ€” real images are copied from the wireframe automatically. If you see one, the source node had no image fill
Text that wrapped onto more lines than the wireframe Expected. Your design system's font is not the wireframe's, so the design is taller

The output is one frame, built as a single undo step โ€” press undo once to remove it entirely. Re-generating the same wireframe replaces its previous output rather than stacking a copy beside it.


If something goes wrong

"Attached to a run already in progressโ€ฆ"
A run for this same frame is still open. Wait for it to finish โ€” only one run per wireframe can be active at a time. A run that never completes blocks new ones until it is cancelled.

"select exactly one frame" / "selected node is not a frame"
The wireframe must be a single FRAME. A group or a multi-selection is refused.

Everything comes out as dashed boxes
The registry is empty for this project, or the wrong file is open. Run the component sync first and check What's in the registry.

A component is placed but shows the wrong variant
The registry knows the component but not which variant to use. Re-run the component sync so the variant capture records each variant's own contents.

The plugin shows a stale state after an update
Close and reopen the plugin โ€” the UI is bundled, so a reload picks up the current build.


What it does not do

Stated plainly, so the output is read correctly:

  • It does not invent components. Anything the design system has no component for stays unmatched.
  • It does not restyle your wireframe's structure. Layout, order and copy are preserved by design โ€” if the wireframe is wrong, the design will be faithfully wrong.
  • It does not replace design review. Confidence and flags mark what to check, not what is correct.

Local Operations and Evaluation

WF2Des converts a registered Figma wireframe into native Figma nodes using the project's component library and design rules. This section covers local operation, diagnosis, and model evaluation. Run commands from the guinness-ai-v2 root.

Prerequisites

  • Copy apps/wf2des/.env.example to apps/wf2des/.env.dev and configure Figma OAuth (preferred) or FIGMA_PAT, plus the required model-provider credentials.
  • Start the local backend/harness, LocalStack on port 4566, and the populated Mongo instance on port 27019.
  • Run uv sync once.

Process queued jobs

# Terminal 1: generation queue
uv run python -u apps/wf2des/scripts/consume_local.py

# Terminal 2: onboarding, component, and actual-render review events
LOCAL_SQS_QUEUE_URL=http://localhost:4566/000000000000/wf2des-events \
  LOCAL_SQS_VISIBILITY_TIMEOUT=1800 uv run python -u apps/wf2des/scripts/consume_local.py

Both bridges are required for the complete local plugin flow. The first handles generation; the second handles registration, sweeps, captures, and the post-placement visual review. Add --once to either command to drain currently available messages and exit. These are mutating production-path runs: they consume SQS messages, read Figma, call configured models, write Mongo/S3, and send the local status webhook. The bridge checks source mtimes before each message and stops when its loaded worker code is stale. Restart it after code changes.

Safe inspection and replay

Command Use Mutation and cost
uv run python apps/wf2des/scripts/inspect_local.py 1 7 Inspect collection counts and tenant-scoped records Read-only
uv run python apps/wf2des/scripts/replay_generation.py RUN_ID --output-dir /tmp/wf2des-replay Reassemble with the original run's pinned source, components, rules, models, and prompt version Local files only; no DB/S3/webhook/ledger mutation; model calls may cost money
uv run python apps/wf2des/scripts/replay_generation.py RUN_ID --stored --output-dir /tmp/wf2des-replay Export the stored result without reassembly Local files only; no model call
uv run python apps/wf2des/scripts/review_render.py --help Evaluate explicit source/output PNG evidence with the production render reviewer Local files only; no DB/S3/queue/Figma mutation; review model may cost money

Replay preserves the original pins. Supplying a new source manifest is an experiment, not a replay of the original generation, and its output must be labeled accordingly.

Registry maintenance

Command Use Mutation and cost
uv run python apps/wf2des/scripts/sweep_components.py "FIGMA_URL" 7 Run the deterministic REST sweep into local design_component records Mutates local Mongo and snapshot files; no LLM
uv run python apps/wf2des/scripts/classify_slot_roles.py --org 1 --project 7 --dry-run Preview content-vs-placeholder classifications No write; incurs model cost for unclassified strings
uv run python apps/wf2des/scripts/classify_slot_roles.py --org 1 --project 7 Persist classifications Updates project_figma_file.slot_roles; incurs model cost
uv run python apps/wf2des/scripts/tag_component_semantics.py --org 1 --project 7 Preview missing semantic tags No registry write; may incur model cost
uv run python apps/wf2des/scripts/tag_component_semantics.py --org 1 --project 7 --apply Persist component/variant visual semantics Mutates component registry; incurs vision-model cost

Model configuration

Production defaults use openai:gpt-5.4 for matching and whole-screen review and openai:gpt-5.4-mini for vision ingestion. Model IDs are provider-prefixed and pinned at parse time. Direct Anthropic uses an anthropic:... model and ANTHROPIC_API_KEY. OpenRouter uses the OpenAI-compatible transport, OPENAI_BASE_URL=https://openrouter.ai/api/v1, an OpenRouter token in OPENAI_API_KEY, and a model such as openai:anthropic/claude-sonnet-4.6. Set SCREEN_REVIEW_REASONING_EFFORT=none for non-GPT review models.

ab_model_test.py is a paid evaluation tool that writes local output under workspace/ab/; it is not part of production processing.

Failure behavior

Exhausted credits, invalid credentials/access, and unavailable configured models cannot be repaired by redelivery. The worker records a failed artifact/manifest and exposes a safe error to the client. Ordinary rate limits and provider 5xx errors remain retryable and are returned to SQS for redelivery.

The plugin records materialization diagnostics separately. The supported event values are name_fallback, ordinal_fallback, build_error, font_fallback, prop_rejected, unmatched, and preserved.