Wireframing skill for Codex
Settle structure before anyone argues about color. Codex starts with a ranked content inventory, then blocks out the screen as a grayscale HTML page, an SVG image or an .excalidraw file, mobile first and then desktop. It uses realistic copy at real lengths, offers two or three structural alternatives with trade-offs when layout is undecided, and numbers annotations for interactions and states a static picture cannot show.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- wireframing Installs to ~/.agents/skills/wireframing/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install wireframing The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project wireframing Installs to .agents/skills/wireframing/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/wireframing.zipunzip -o wireframing.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) wireframing PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $wireframing, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Produces low-fidelity wireframes as grayscale HTML/CSS pages, hand-written SVG or Excalidraw .excalidraw files - content inventory first, real copy over lorem ipsum, layout at mobile and desktop widths, annotated behaviour notes, and two or three structural alternatives for comparison. Use when asked to wireframe, sketch, mock up or block out a page, screen or flow before visual design, or to explore layout options quickly without committing to styling.
Use it when
- A new page or screen needs its structure agreed before visual design
- You want to compare two or three layout options quickly
- A PR, issue or spec needs a simple screen sketch
- The team works in Excalidraw and wants editable files
Use something else when
- You need a polished, styled interface: use frontend-design
- You only need the path between screens: use user-flows
How to check the result
Each wireframe opens at 375px and 1280px without horizontal overflow, includes every content inventory item, and makes the primary action the most prominent control.
The mistake it prevents
Making wireframes look finished, which pulls review toward colors and fonts instead of structure and content priority.
A wireframe settles structure, priority and content before anyone argues about color. Done well: grayscale only, real or realistic copy, every element there for a reason, both narrow and wide layouts shown, and behaviour that a static picture cannot show written as numbered annotations.
Choose the format
| Need | Format | Why |
|---|---|---|
| Default; clickable, responsive, quick to change | Static HTML + one CSS file | Opens anywhere, shows real reflow, links between screens |
| Image to drop into a doc, PR or issue | SVG | Single file, diffable, no runtime |
| The team sketches together in Excalidraw | .excalidraw JSON | Editable by hand afterwards in excalidraw.com or the VS Code extension |
| Layout options compared side by side | One HTML page with 2-3 variants in columns | Same content, different structure |
Never build wireframes inside the production component library: styling leaks in, and reviewers start commenting on visual design.
Workflow
- Clarify the screen’s job, the primary user and the one primary action.
- Inventory content and actions; rank by priority.
- Sketch the mobile layout first (forces priority), then desktop.
- Produce 2-3 structural alternatives when the layout is undecided.
- Annotate behaviour, states and open questions.
- Review against the content inventory; get a pick before visual design.
1. Content inventory
Before any boxes, write the list. This is where most wireframe value comes from.
Screen: Project overview Job: see project health and act on what is late
Primary action: Create task
| Priority | Content / action | Notes |
|---|---|---|
| 1 | Overdue tasks (count + list) | Most common reason to visit |
| 2 | Create task | Primary button |
| 3 | Progress this week | Simple number + bar |
| 4 | Team members | Avatars, link to manage |
| 5 | Activity feed | Collapsible on mobile |
Pull real labels and data shapes from the codebase or API if the feature exists
(rg -n "interface Project|type Project" src) so the wireframe reflects real field
lengths and counts.
2. HTML wireframe kit
Use one stylesheet that makes everything look like a wireframe:
/* wire.css */
:root { --ink:#222; --mid:#888; --line:#bbb; --fill:#eee; --bg:#fff; font: 15px/1.45 system-ui, sans-serif; color: var(--ink); }
* { box-sizing: border-box; }
body { margin: 0; background: var(--bg); }
.page { max-width: 1200px; margin: 0 auto; padding: 16px; display: grid; gap: 16px; }
.box { border: 1.5px solid var(--line); border-radius: 6px; padding: 12px; background: var(--bg); }
.img { background: var(--fill) linear-gradient(to top right, transparent 49.5%, var(--line) 50%, transparent 50.5%),
linear-gradient(to top left, transparent 49.5%, var(--line) 50%, transparent 50.5%); min-height: 120px; border: 1.5px solid var(--line); }
.btn { display: inline-block; border: 1.5px solid var(--ink); border-radius: 6px; padding: 8px 14px; font-weight: 600; background: var(--bg); }
.btn.primary { background: var(--ink); color: var(--bg); }
.line { height: 10px; background: var(--fill); border-radius: 3px; margin: 6px 0; }
.note { counter-increment: note; position: relative; }
.note::after { content: counter(note); position: absolute; top: -10px; right: -10px; width: 22px; height: 22px;
border-radius: 50%; background: #ffd400; color: #000; font: 700 12px/22px system-ui; text-align: center; }
@media (min-width: 900px) { .split { display: grid; grid-template-columns: 2fr 1fr; gap: 16px; } }
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>WF - Project overview</title><link rel="stylesheet" href="wire.css"></head>
<body><main class="page">
<header class="box" style="display:flex;justify-content:space-between;align-items:center">
<strong>Atlas redesign</strong><a class="btn primary note" href="create-task.html">Create task</a>
</header>
<div class="split">
<section class="box note"><h2>Overdue (4)</h2>
<p>Write migration guide - due Mon - Priya</p><p>Fix export timeout - due Tue - Sam</p>
<a href="#">View all overdue</a></section>
<aside class="box"><h3>This week</h3><p>18 of 31 done</p><div class="line" style="width:58%"></div></aside>
</div>
</main></body></html>
Rules for the kit: one gray ink, one fill, a single accent reserved for annotation markers. No brand colors, no icons beyond simple shapes, no shadows. System font only. Real headings and text, so content length problems show up now.
3. SVG wireframe
For a static image, draw on an 8px grid with a fixed width artboard:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 390 600" font-family="system-ui, sans-serif" font-size="14">
<rect width="390" height="600" fill="#fff"/>
<rect x="16" y="16" width="358" height="48" rx="6" fill="none" stroke="#bbb" stroke-width="1.5"/>
<text x="32" y="46" font-weight="600">Atlas redesign</text>
<rect x="16" y="80" width="358" height="160" rx="6" fill="none" stroke="#bbb" stroke-width="1.5"/>
<text x="32" y="108" font-weight="600">Overdue (4)</text>
<text x="32" y="136" fill="#555">Write migration guide - Mon</text>
<rect x="16" y="528" width="358" height="48" rx="6" fill="#222"/>
<text x="195" y="557" fill="#fff" text-anchor="middle" font-weight="600">Create task</text>
</svg>
4. Excalidraw file
An .excalidraw file is JSON. Generate it with a short script rather than by hand when
there are more than a few elements; give each element a unique id and random seed.
{
"type": "excalidraw", "version": 2, "source": "codex-wireframe",
"elements": [
{ "id": "hdr", "type": "rectangle", "x": 0, "y": 0, "width": 360, "height": 48,
"strokeColor": "#1e1e1e", "backgroundColor": "transparent", "fillStyle": "solid",
"strokeWidth": 1, "strokeStyle": "solid", "roughness": 1, "opacity": 100,
"angle": 0, "seed": 1201, "version": 1, "versionNonce": 1, "isDeleted": false,
"groupIds": [], "boundElements": [], "roundness": { "type": 3 }, "locked": false, "link": null, "updated": 1 },
{ "id": "hdr-t", "type": "text", "x": 16, "y": 14, "width": 160, "height": 20,
"text": "Atlas redesign", "originalText": "Atlas redesign", "fontSize": 16, "fontFamily": 2,
"textAlign": "left", "verticalAlign": "top", "containerId": null, "lineHeight": 1.25,
"strokeColor": "#1e1e1e", "backgroundColor": "transparent", "fillStyle": "solid",
"strokeWidth": 1, "strokeStyle": "solid", "roughness": 1, "opacity": 100,
"angle": 0, "seed": 1202, "version": 1, "versionNonce": 2, "isDeleted": false,
"groupIds": [], "boundElements": [], "roundness": null, "locked": false, "link": null, "updated": 1 }
],
"appState": { "viewBackgroundColor": "#ffffff", "gridSize": null },
"files": {}
}
Excalidraw repairs many missing fields on load, but always open the file once to confirm it imports (excalidraw.com needs network; the VS Code extension works offline).
Layout alternatives
When structure is undecided, show 2-3 variants with identical content and name the trade-off of each:
| Variant | Structure | Good for | Cost |
|---|---|---|---|
| A | List-first, stats in sidebar | Daily triage | Stats less visible on mobile |
| B | Stats cards on top, list below | Weekly check-ins | Pushes overdue list below fold |
| C | Tabs: Overdue / This week / Activity | Small screens | Hides information behind taps |
Annotations
Number markers on the wireframe map to a list below it:
1. Create task opens a side sheet on desktop, full screen on mobile. Keeps project context.
2. Overdue list shows max 5; "View all" goes to filtered task list. Empty: "Nothing overdue".
Open questions: Do guests see the Team section?
Cover what a picture cannot: interactions, states (empty, loading, error, long content), responsive changes, data rules, and permission differences.
Gotchas
- Lorem ipsum hides the real problem: a 60-character task name or a German label. Use realistic copy at realistic lengths.
- Polished wireframes get visual feedback instead of structural feedback. Keep them ugly.
- Wireframing only desktop lets the mobile layout become an afterthought.
- Every element should trace back to the content inventory; if it does not, cut it or add it to the inventory with a reason.
Verification
- Open the HTML at 375px and 1280px wide; nothing overflows horizontally.
- Every inventory item appears on the wireframe, in priority order of visual weight.
- The primary action is the most prominent control on both widths.
- Each annotation number exists on the wireframe and in the list.
Output
wireframes/<feature>/
wire.css
index.html # links to every screen and variant
<screen>.html | <screen>.svg | <feature>.excalidraw
notes.md # inventory, annotations, variants and trade-offs, open questions
Related: map the path between screens with $user-flows; when a direction is chosen,
move to visual design with $frontend-design.
What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "Wireframing"
short_description: "Settle structure before anyone argues about color"
default_prompt: "$wireframing Wireframe a project overview screen for mobile and desktop before we design it" About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.