/variate
Puts real design variations of one project file on the user's own localhost, behind a small card that flips them with the arrow keys, then keeps listening for their verdict. Use when the user wants design variations, alternatives, or directions to choose between; asks to try a
$ npx -y skills add nutlope/variate --skill variate --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/variate
Context preview
The summary Claude sees to decide when to auto-load this skill.
Puts real design variations of one project file on the user's own localhost, behind a small card that flips them with the arrow keys, then keeps listening for their verdict. Use when the user wants design variations, alternatives, or directions to choose between; asks to try a
SKILL.md
variate.SKILL.mdname: variate
description: >
Puts real design variations of one project file on the user's own localhost,
behind a small card that flips them with the arrow keys, then keeps
listening for their verdict. Use when the user wants design variations,
alternatives, or directions to choose between; asks to try a different
hero, layout, palette, section, or page; wants to design something new and
compare a few takes; clicked the card (a vary, more, or done ask is
queued); or wants to continue or finish a variate session. It works in an
empty folder (serves a page, drafts four fresh designs) and in a real
project (varies one file in place), on any stack. Not for a single change
with one right answer, a refactor, or a non-visual edit: just edit the
file for those.
license: MIT
compatibility: Requires Node.js 18+. Works with or without a dev server.
metadata:
version: "3.2.0"
author: youssef
hooks:
Stop:
- hooks:
- type: command
timeout: 15
command: node "${CLAUDE_SKILL_DIR:-$HOME/.claude/skills/variate}/scripts/await.mjs" --ws "${CLAUDE_PROJECT_DIR:-$PWD}/.variate" --peek --hook
- type: command
timeout: 920
asyncRewake: true
command: node "${CLAUDE_SKILL_DIR:-$HOME/.claude/skills/variate}/scripts/await.mjs" --ws "${CLAUDE_PROJECT_DIR:-$PWD}/.variate" --wake --timeout 900variate
The user's own localhost is the canvas. You write real alternatives of one of their files; a small card at the bottom of their page lets them flip between them; the one they keep is the code. There is no studio, no preview server of ours, and no separate thing to keep in sync.
Critical floor
Obey these even if you read nothing else.
1. **Variant 1 is the user's file as it was.** Never edit it, never delete it, never overwrite it. Everything you write is a new numbered sibling. 2. **Every variant is a complete, drop-in replacement for the target file.** Same exports, same props, same imports the app relies on. It must run. 3. **Speak the project's own language.** Its design tokens, its utility classes, its components, its fonts, its real copy. A variant that adds a dependency or invents a colour has already failed. 4. **Four positions that disagree.** Each changes something different, and `plan.json` says what and what it costs. Four tweaked card grids is wallpaper, not a round. Write `plan.json` before the variants; `check` lints it. 5. **A round narrows, it never accumulates.** Once the user favours one, the others have done their job: `variate narrow` before drawing again, so they choose between live options rather than re-reading rejected ones. It hides rather than destroys, in `.variate/<set>/.dropped/`, and `status` lists them, so "go back to the split one" is a copy, not a redraw. 6. **Talk in positions, never filenames.** "2 of 4", not "3.tsx". 7. **Ask one question per round, with your recommendation.** 8. **Presenting a round never ends your turn.** Hand it over, then run the listening loop below. The card's keep, refine and pick land there. 9. **Drain before you answer, every turn a round is open.** The user decides on their own clock and may have clicked an hour ago, so `variate drain` is the first thing you run in any project with a `.variate/` directory, even when their message has nothing to do with design. An ask left sitting is the user waiting for an answer you already have. 10. **Never write the target file directly while a set is open.** Write a variant and switch to it. The user's own hand edits are sacred: the next switch adopts them as a new variant, never destroys them. 11. **`variate end` when the session is done.** `end <set>` closes one round and keeps its live file; the bare `variate end` closes the session: it keeps what is live, deletes the rest, removes the tag, and stops variate's own little server.
The commands
`<skill>` below is this skill's own directory, the one holding this file. **Every command takes `--root <project>`**; pass it explicitly, since many harnesses reset the working directory between calls.
node <skill>/variate.mjs up --root <project> card appears on their page
node <skill>/variate.mjs add <file> [--n 4] [--new] register a set
node <skill>/variate.mjs check <set> lint before you present
node <skill>/variate.mjs use <set> <n> put one on their page
node <skill>/variate.mjs status every set, and which position is live
node <skill>/variate.mjs peek is anything queued? counts only, claims nothing
node <skill>/variate.mjs narrow <set> [<n>] keep one, drop the rest, draw again from there
node <skill>/variate.mjs await [--timeout 20] block briefly for the card's next ask
node <skill>/variate.mjs drain [--ack <id> --note "..."] claim every queued ask now
node <skill>/variate.mjs end [<set>] keep what is live, clean up
Exit codes: **0** did it, **1** error, **2** nothing to do, **3** the user has to act. `up` exits 3 when a sandbox blocks the card: not a failure, everything else works and the user reloads to see each switch. `await`, `drain` and `peek` exit 0 even when quiet, because hearing nothing is them working: read their JSON, never their exit code. Their one non-zero is `await`'s 3, "no card runs, so no ask can ever arrive": skip the loop and ask in chat.
The one model
A **set** is one target file plus N alternatives in `.variate/<set>/`: `target` (one line: the path), `plan.json` (the round's question and one entry per position), `1.ext` (their file, untouched), and your `2..N`. Switching copies a variant over the target file and their dev server re-renders. Which variant is live is **derived** by hashing, never stored, so it cannot drift. Three words, one thing each: a **variant** is a
Read more
name: variate
description: >
Puts real design variations of one project file on the user's own localhost,
behind a small card that flips them with the arrow keys, then keeps
listening for their verdict. Use when the user wants design variations,
alternatives, or directions to choose between; asks to try a different
hero, layout, palette, section, or page; wants to design something new and
compare a few takes; clicked the card (a vary, more, or done ask is
queued); or wants to continue or finish a variate session. It works in an
empty folder (serves a page, drafts four fresh designs) and in a real
project (varies one file in place), on any stack. Not for a single change
with one right answer, a refactor, or a non-visual edit: just edit the
file for those.
license: MIT
compatibility: Requires Node.js 18+. Works with or without a dev server.
metadata:
version: "3.2.0"
author: youssef
hooks:
Stop:
- hooks:
- type: command
timeout: 15
command: node "${CLAUDE_SKILL_DIR:-$HOME/.claude/skills/variate}/scripts/await.mjs" --ws "${CLAUDE_PROJECT_DIR:-$PWD}/.variate" --peek --hook
- type: command
timeout: 920
asyncRewake: true
command: node "${CLAUDE_SKILL_DIR:-$HOME/.claude/skills/variate}/scripts/await.mjs" --ws "${CLAUDE_PROJECT_DIR:-$PWD}/.variate" --wake --timeout 900variate
The user's own localhost is the canvas. You write real alternatives of one of their files; a small card at the bottom of their page lets them flip between them; the one they keep is the code. There is no studio, no preview server of ours, and no separate thing to keep in sync.
Critical floor
Obey these even if you read nothing else.
1. **Variant 1 is the user's file as it was.** Never edit it, never delete it, never overwrite it. Everything you write is a new numbered sibling. 2. **Every variant is a complete, drop-in replacement for the target file.** Same exports, same props, same imports the app relies on. It must run. 3. **Speak the project's own language.** Its design tokens, its utility classes, its components, its fonts, its real copy. A variant that adds a dependency or invents a colour has already failed. 4. **Four positions that disagree.** Each changes something different, and `plan.json` says what and what it costs. Four tweaked card grids is wallpaper, not a round. Write `plan.json` before the variants; `check` lints it. 5. **A round narrows, it never accumulates.** Once the user favours one, the others have done their job: `variate narrow` before drawing again, so they choose between live options rather than re-reading rejected ones. It hides rather than destroys, in `.variate/<set>/.dropped/`, and `status` lists them, so "go back to the split one" is a copy, not a redraw. 6. **Talk in positions, never filenames.** "2 of 4", not "3.tsx". 7. **Ask one question per round, with your recommendation.** 8. **Presenting a round never ends your turn.** Hand it over, then run the listening loop below. The card's keep, refine and pick land there. 9. **Drain before you answer, every turn a round is open.** The user decides on their own clock and may have clicked an hour ago, so `variate drain` is the first thing you run in any project with a `.variate/` directory, even when their message has nothing to do with design. An ask left sitting is the user waiting for an answer you already have. 10. **Never write the target file directly while a set is open.** Write a variant and switch to it. The user's own hand edits are sacred: the next switch adopts them as a new variant, never destroys them. 11. **`variate end` when the session is done.** `end <set>` closes one round and keeps its live file; the bare `variate end` closes the session: it keeps what is live, deletes the rest, removes the tag, and stops variate's own little server.
The commands
`<skill>` below is this skill's own directory, the one holding this file. **Every command takes `--root <project>`**; pass it explicitly, since many harnesses reset the working directory between calls.
node <skill>/variate.mjs up --root <project> card appears on their page node <skill>/variate.mjs add <file> [--n 4] [--new] register a set node <skill>/variate.mjs check <set> lint before you present node <skill>/variate.mjs use <set> <n> put one on their page node <skill>/variate.mjs status every set, and which position is live node <skill>/variate.mjs peek is anything queued? counts only, claims nothing node <skill>/variate.mjs narrow <set> [<n>] keep one, drop the rest, draw again from there node <skill>/variate.mjs await [--timeout 20] block briefly for the card's next ask node <skill>/variate.mjs drain [--ack <id> --note "..."] claim every queued ask now node <skill>/variate.mjs end [<set>] keep what is live, clean up
Exit codes: **0** did it, **1** error, **2** nothing to do, **3** the user has to act. `up` exits 3 when a sandbox blocks the card: not a failure, everything else works and the user reloads to see each switch. `await`, `drain` and `peek` exit 0 even when quiet, because hearing nothing is them working: read their JSON, never their exit code. Their one non-zero is `await`'s 3, "no card runs, so no ask can ever arrive": skip the loop and ask in chat.
The one model
A **set** is one target file plus N alternatives in `.variate/<set>/`: `target` (one line: the path), `plan.json` (the round's question and one entry per position), `1.ext` (their file, untouched), and your `2..N`. Switching copies a variant over the target file and their dev server re-renders. Which variant is live is **derived** by hashing, never stored, so it cannot drift. Three words, one thing each: a **variant** is a
A compact design skill that generates four design variations of a component to iterate better on your UIs. A skill for Claude Code, Codex CLI, and opencode.

