design-from-code
Verify facts in code → agree on HTML → lock it in a .md → delegate the build.
A workflow skill for Claude Code and OpenAI Codex that designs changes to existing UI from the real source — not from imagination.




Actual output of the skill (issue #976): the current bar reproduced from MobileBottomBar.tsx (AS-IS), the proposed change (TO-BE — green = new / yellow = changed), and the data-zero empty state — all as one self-contained HTML file, zero dependencies.
Before drawing anything, it reads the actual component JSX and traces the data model in code, then reproduces the current screen pixel-for-pixel and iterates self-contained HTML mockups until you approve. The result is a design doc grounded in facts, ready to hand to an implementer.
Built and maintained by the team behind nlook.me — a publishing platform where writers ship documents and watch readership grow. The worked example here is a real nlook feature.
Why this exists
Most "design a UI change" prompts fail the same two ways:
- The model guesses how the data works. "What does this visitor count actually count?" — if you imagine the answer, you are wrong ~100% of the time. This skill traces handler → use-case → repository → schema and confirms it as fact before designing.
- The mockup is schematic, so it doesn't match reality. This skill reads the actual JSX (render functions, class names, labels, spacing) and reproduces the current component so the proposal sits believably inside the real product.
It also bakes in the things people forget: one decision at a time, explicit keep / new / changed tags, and the empty (data-zero) state as a first-class screen.
What you get
- An 8-step workflow (issue → code map → data verification → HTML mockup → confirm → faithful AS-IS/TO-BE → design doc → delegated build + verify)
- Self-contained HTML mockups: phone frames, inline-SVG charts (no chart library), monotone big numbers, keep/new/changed outlines, empty states
- A restraint-by-default guardrail against the generic "AI look" (no emoji-icons, gradient blobs, or rainbow accents) — it matches your product's real tokens or a reference you give, and is fully overridable
- A portable
.design/ output format that persists every mockup with its decisions, verified data meanings, and version history — so designs outlive the session and any viewer can load them
- Reference guides for each hard part and a fully worked real example
Install
This repo is both a Claude Code plugin and a plain skill folder. Pick one path.
Option A — Claude Code plugin (recommended)
From inside Claude Code:
/plugin marketplace add nlook-service/design-from-code
/plugin install design-from-code@design-from-code
The first command registers this repo as a marketplace; the second installs the bundled skill. Restart the session and the design-from-code skill is available.
Replace nlook-service/design-from-code with your fork's owner/repo if you forked it.
Option B — Manual skill install (Claude Code or Codex)
Both tools read the same SKILL.md format and load skills from a skills/ directory.
git clone https://github.com/nlook-service/design-from-code.git
cd design-from-code
# Claude Code (user-wide)
ln -s "$PWD/skills/design-from-code" ~/.claude/skills/design-from-code
# OpenAI Codex CLI (user-wide)
ln -s "$PWD/skills/design-from-code" ~/.codex/skills/design-from-code
Use cp -r instead of ln -s if you prefer a copy. For a single project only, symlink into that repo's .claude/skills/ instead of the home directory.
Updating (already installed?)
There's no build step — updating just means getting the new files in place and starting a fresh session. How depends on how you installed:
| Installed via | How to update |
|---|
| Plugin (Option A) | In Claude Code, open /plugin, refresh the design-from-code marketplace and update the plugin (or uninstall then install again). |
Symlink ln -s (Option B) | git pull in your clone — the symlink already points at it, so that's the whole update. |
Copy cp -r (Option B) | git pull, then re-run the same cp -r skills/design-from-code <dest> to overwrite the installed copy. |
Then start a fresh session (the host only scans skills at session start) and run bash verify.sh to confirm. Check the installed version in .claude-plugin/plugin.json, and see CHANGELOG.md for what changed.
Your existing .design/ outputs are safe — they live in your own project repos, not in the skill, so updating never touches them.
Verify your install
Three quick levels — run the first one, do the others once.
1. Files & manifests are intact (one command):
bash verify.sh
Expected: a list of ✓ checks ending in PASS — N checks ok. It validates the skill frontmatter, the name/folder match, bilingual triggers, every referenced file, the self-contained example, the plugin JSON, and (if installed) that the symlinks resolve. Exit code 0 on success, so you can wire it into CI.
2. It actually loads (fresh session):
- Claude Code: start a new session and type
/design-from-code. It should appear and load. Running /help or the skill picker should list it with the English description.
- Codex: start a session;
design-from-code should be in the skill list.
3. It actually triggers and produces a mockup (the real test):
In a repo that has some UI, say:
Design how to add a "last updated" label to the existing card header. Mockup first.
You should see it (a) read the real component, (b) ask one narrow question, and (c) hand you a self-contained .html you can open in a browser. That round-trip — real source → HTML you can see — is the skill working end to end. Korean works too: try "이 카드 헤더에 ~ 추가 설계해줘".
The example artifact is pre-rendered, so you can sanity-check the output shape before installing: open examples/mobile-bottom-brand-status-v5.html in any browser.
How loading works (you probably don't need to "load" anything)
After install you don't import or enable the skill anywhere. There are exactly two ways it fires — and the everyday one needs no command at all.
| How you trigger it | When to use |
|---|
| Automatic (default) | Just describe the task in plain language: "Design how this card should look — mockup first." | Almost always. This is the intended path. |
| Explicit | Type /design-from-code (Claude Code) or pick it from the skill list (Codex) | When you want to force it, or auto-matching didn't catch an unusual phrasing |
Either way, start a fresh session after installing — the host only scans skills at session start.
What happens under the hood
You don't keyword-match; the model does an intent match. Here is the actual mechanism, so the behavior isn't a black box:
- At session start — Claude Code / Codex loads only the frontmatter of every installed skill (its
name and description) into context. The full SKILL.md body and the references/ files are not loaded yet, which keeps your context cheap.
- On each message — the model compares what you asked against those
description lines and decides whether one matches.
- On a match — it loads that skill's full body and starts the workflow. Only then does it read the reference guides it needs.
So the description: field in skills/design-from-code/SKILL.md is the entire trigger surface. The phrases written there are examples that bias the match — not a fixed keyword list the model checks literally:
| Language | Example trigger phrases |
|---|
| 🇬🇧 English | "design this" · "make a mockup" · "how should this feature look" · "add ~ to the existing screen" |
| 🇰🇷 Korean | "설계해줘" · "시안 만들어줘" · "이 기능 어떻게 보여줄지" · "기존 화면에 ~ 추가" |
Anything close in meaning to these will trigger it — you don't have to say them word-for-word. To see or extend the list, open the description: line in SKILL.md.
Languages — what you do and don't do
You do nothing per language. One install covers every language. There is no separate Korean build, no locale flag, no config.
| Behavior | Why |
|---|
| English & Korean | Trigger most reliably | Their phrases are written into the description, so the match is strongest |
| Other languages (Japanese, Chinese, Spanish, …) | Still work | Matching is semantic, not literal — 「このカードにラベルを追加する設計をして」 maps to the same intent even though it isn't listed |
| Any language, edge phrasing | Use /design-from-code | The explicit command bypasses matching entirely and always works |
If you want another language to fire as reliably as EN/KO, add a few of its trigger phrases to the single description: line in skills/design-from-code/SKILL.md (keep it one line), then re-run bash verify.sh and restart the session. Nothing else changes — the workflow body itself is language-agnostic and the model replies in whatever language you wrote in.
Usage
Trigger it with any UI-design request that touches existing code:
Issue #976: add a brand-status card (posts / visitors / likes) to the mobile
bottom bar. Show me a mockup first.
The skill then runs:
| # | Step | What happens |
|---|
| 1 | Read the issue | gh issue view (needs gh auth login for GitHub issues) |
| 2 | Map the code | Explore agents return the relevant components/hooks/schema |
| 3 | Verify the data | Trace handler→query→schema; confirm what each number actually means |
| 4 | HTML mockup v1 | Phone frames, 2–3 options, empty state, inline SVG — written to .design/<slug>/ |
| 5 | Confirm | One decision at a time; bump to v2, v3… per feedback |
| 6 | Faithful AS-IS/TO-BE | Read real JSX, reproduce 1:1, tag keep/new/changed |
| 7 | Design doc .md | Approved mockup + verified data model + build entry points |
| 8 | Delegate + verify | Hand to a language-expert agent; close with build/type-check/tests |
See examples/ for a runnable HTML deliverable and the issue-976 walkthrough for the full v1→v5 story (including where the user corrected the layout).
Output — the .design/ artifact format
Steps 4–7 don't just chat mockups at you and vanish; they persist to a small, tool-agnostic format inside your project, so a design (and why it ended up that way) survives the session and can be browsed later.
The point is a clean separation — three things that change at different rates and shouldn't be bundled:
| Layer | What | Where it lives |
|---|
| Method | how to design (this skill) | the skill's Markdown — stateless, shareable |
| Data | the mockups + decisions + verified facts | .design/ in your repo — grows over time |
| Viewer | the "spec tool" gallery/timeline UI | a separate program that only reads .design/ |