Skip to content
Design
Skill

/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

BOOST
From plugin
variate
2131 skill
Install
$ npx -y skills add nutlope/variate --skill variate --agent claude-code

How 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.md
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 900

variate

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
Ships withvariate

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.

Get the whole plugin
Stats
213
Stars
11
Forks
Maintained
Maintenance
JavaScript
Language
MIT
License
2mo ago
Last commit
3mo ago
Created
4d ago
Added

Repo: nutlope/variate