penpot-build-screen
Design production-grade screens in Penpot from a brief, as a senior visual designer — reusing the existing design system (tokens + components) and assembling section by section, never one-shot. Use to create a screen/page/landing/dashboard from a description. NOT for translating existing code (use penpot-build-from-code). Triggers: 'design a dashboard', 'create a landing page', 'design this app screen', 'build a UI from this brief', 'design a settings page', 'mock up a screen in Penpot'.
Why we recommend it: Designs production-grade screens in Penpot from a brief, reusing design system tokens and components, section by section. Can build dashboards but is a general screen-building workflow, not dashboard-specific.
Inspect before use
Read the source instructions and check the requirements before you install this skill.
SKILL.md
The saved excerpt is a snapshot from when this skill was listed. The external source remains the complete and most current version.
---
name: penpot-build-screen
description: "Design production-grade screens in Penpot from a brief, as a senior visual designer — reusing the existing design system (tokens + components) and assembling section by section, never one-shot. Use to create a screen/page/landing/dashboard from a description. NOT for translating existing code (use penpot-build-from-code). Triggers: 'design a dashboard', 'create a landing page', 'design this app screen', 'build a UI from this brief', 'design a settings page', 'mock up a screen in Penpot'."
disable-model-invocation: false
version: 0.4.0
audiences: [product-designer]
mode-default: review
requires:
- shared/penpot-mcp-tool-reference.md
- shared/plugin-api-gotchas.md
- shared/tokens-schema.json
- shared/naming-conventions.md
- shared/state-management.md
- shared/modes-and-policies.md
- shared/visual-self-review.md
- shared/design-quality.md
- shared/report-schemas/design-quality-report.schema.json
- shared/visual-effects.md
---
# penpot-build-screen — brief to on-system screen
## 1. Title + How it works
`penpot-build-screen` turns a brief into a crafted, on-system screen; every mutation goes through
`execute_code`; validate visually with `export_shape`; read structure with
`penpotUtils.shapeStructure` (full tool surface: `shared/penpot-mcp-tool-reference.md`). It first
discovers the existing design system (tokens + components via `penpot-foundations` / the local
library), then builds the screen **section by section** inside flex Boards, binding tokens and reusing
components — never generating an entire screen in one call.
## 2. The One Rule That Matters Most
**Reuse the system; build incrementally.** Prefer existing components and semantic tokens over raw
shapes. Build one section, checkpoint with an `export_shape`, then continue. If no system exists,
bootstrap only a minimal one (hand off to `penpot-foundations` for anything substantial).
## 3. Penpot MCP Tool Reference
Full surface: `shared/penpot-mcp-tool-reference.md`. Key calls: `penpot.createBoard()`/`addFlexLayout()`
for the screen and sections; `penpot.library.local.components` + `comp.instance()` to reuse components;
`shape.applyToken` for token binding; `export_shape('selection'|'page')` at checkpoints.
## 4. Plugin API Essentials
Gotcha numbers refer to `shared/plugin-api-gotchas.md`.
- Screen and sections are **Boards** with flex layout; compose with append order + gaps + align/justify.
- Reuse components via `component.instance()`; don't redraw system parts as raw shapes.
- **#3 text auto-sizing** — set `growType` to `auto-width`/`auto-height` AFTER any `resize()` (which forces `fixed`).
- **#4 flex overrides child x/y** — use `layoutChild` for stretch/margins.
- Bind colors/spacing/radius/type to **semantic tokens**, never hardcoded.
- **#11 every new Board is born with an OPAQUE WHITE fill — this skill's critical failure mode.** `createBoard()` ships `fills = [{ fillColor: "#FFFFFF", fillOpacity: 1 }]`; left in place, a structural wrapper's square white corners poke out behind rounded children (radius looks broken), and layout boards keeping the literal white never flip in dark mode (no token, off-system). **Fill policy:** decide per board — a **structural** board (layout-only chrome: sections, rows, wrappers) gets `board.fills = []`; a **surface** (screen bg, card, sheet, button) binds a `color.bg.*` token, never a literal. Default layout containers to transparent (`shared/modes-and-policies.md`).
- **#13b exact font match** — `penpot.fonts.all.find(f => f.name === "…")`; `findByName` is a substring search.
- **#15** — set `layoutChild.*` only AFTER `appendChild`; `openPage` is async (two-call protocol: create+open, then assert `currentPage.id` before any `createBoard`).
- **#16** — run `clearFlip` after every section (fill-sized children can come back with `flipX = true`; canonical helper in `shared/visual-effects.md`).
- **#17** — `await board.waitForLayoutUpdate()` before reading geometry (replaRead the full source on GitHub (opens external page)