prototype
Build a throwaway prototype that answers one design question before the real build - whether a state model or piece of logic holds up on awkward cases, what a screen could look like, or whether a library, API or approach behaves the way you need.
- Use it when
- The user says "prototype this", "spike it", "mock it up", "let me try it before we build it", "does this state model hold up", "what should this look like", "try both approaches", or when a plan has an open question that is cheaper to run than to argue about. Writes the question down first, builds the smallest runnable thing, keeps the answer and lets the code go. Not for production code, a feature whose design is already decided, writing a spec, or fixing a bug.
- What kind it is
- A written method: it lays out how the work is done and what to check along the way.
- Size
- 1,339 words. The whole text loads when the skill fires; only the 132-word description is always loaded.
- Starts with
- Ask for the job it describes.
How it is organised
What’s inside
The skill’s top-level sections, in order. The bar is each section’s share of the 1,339 words, so you can see where the weight sits before reading.
- 11. Write the question first119 words
- 22. Pick the kind of probe435 words
- 33. Rules for every prototype216 words
- 44. Finish: keep the answer, not the code236 words
- 5Example184 words
- 6Signs it is drifting56 words
The skill itself
Read it before you install it
prototype/SKILL.md · 1,339 wordsDownloadSkill on GitHub ↗---
name: prototype
description: Build a throwaway prototype that answers one design question before the real build - whether a state model or piece of logic holds up on awkward cases, what a screen could look like, or whether a library, API or approach behaves the way you need. Use when the user says "prototype this", "spike it", "mock it up", "let me try it before we build it", "does this state model hold up", "what should this look like", "try both approaches", or when a plan has an open question that is cheaper to run than to argue about. Writes the question down first, builds the smallest runnable thing, keeps the answer and lets the code go. Not for production code, a feature whose design is already decided, writing a spec, or fixing a bug.
license: MIT
---
# Prototype
A prototype is throwaway code that answers one question. The code is disposable. The answer is what you keep.
Used well, it replaces an argument or a long spec with something the user can run and poke. Used badly, it quietly turns into the first draft of production code, with all the shortcuts still in it.
## 1. Write the question first
Before any code, write one sentence: what is being decided, and which answer would change the plan. If the request or plan already contains the question, quote it as it stands.
- No question, no prototype. If the design is settled, build the feature properly with tests first (see `test-driven-development`).
- Two questions are two prototypes. A prototype that answers a neighbouring question still runs, so nobody notices it was wasted.
- Note the limits: what the prototype may touch, and what observation would count as an answer.
If the question changes shape part-way (a new constraint, a different library, a different data shape), start again from the new question. A prototype patched across two questions answers neither reliably.
## 2. Pick the kind of probe
| The question is | Build |
|---|---|
| "Does this logic or state model hold up?" | A logic probe |
| "What should this look like?" | A set of UI variants |
| "Does this library, API or approach behave as we need?" or "is X or Y better?" | A feasibility probe |
The kinds produce very different artifacts, and choosing wrongly wastes the whole prototype. If the question is ambiguous, ask the user. If they cannot be reached, choose from the surrounding code (a backend module means logic, a page or component means UI, a third-party dependency or a speed question means feasibility) and write the assumption at the top of the prototype.
### Logic probe
Split what you build in two:
- **Pure core.** The state model or logic the question is about, with no database, network client or framework wiring. This is the part you are learning about.
- **Throwaway shell.** Whatever lets someone drive the core and watch it. Name it as throwaway.
For a non-developer, make the shell a single self-contained file they can open with a double-click: a control for each action, plus a few guided walkthroughs (tabs or steps) that push the model through the cases that are hard to reason about on paper. For a developer, a small interactive terminal program is enough. After every action, show the full relevant state.
Run the scenarios yourself first and record what the state actually did. The answer is what happened, not whether it looks right. When a scenario ends in a situation whose answer changes what the product does, ask the user about that concrete case ("a refund after the invoice closed: allowed?") and not "does this look right?". Record their answer.
### UI variants
Build several radically different variations of the same screen: different structure and interaction, not colour tweaks. Put them behind one switch on one route or entry point (a URL query parameter such as `?variant=b`, a flag, or a setting) and add a visible switcher so the user can flip between them. Use realistic content, and show the relevant state when the variant changes. The user chooses; you do not.
### Feasibility probe
Write a small script or test that exercises the real library, API or approach on realistic input and prints what it observed. Include the awkward cases: bad input, large input, slow or failing dependencies. When comparing approaches, put every variant behind one switch in the same build and run them under identical conditions (same input, same machine, same measurement). Separate scripts drift apart and quietly contaminate the comparison.
## 3. Rules for every prototype
1. **Disposable and labelled.** The name or a comment says it is a prototype. Put it near the code it concerns so the context is obvious, in a path that cannot be mistaken for production, and follow the project's existing conventions instead of inventing a top-level structure.
2. **One command to run.** Use the project's task runner or a plain `python path`, `make name`, `cargo run --bin name`. Starting it should need no thought.
3. **No persistence by default.** State lives in memory. If persistence is the question, use a scratch store named so that it is obviously safe to wipe.
4. **Skip the polish.** No test suite, no error handling beyond what keeps it running, no abstractions. The only checks worth writing are the small assertions, measurements or visible observations that produce the answer.
5. **Stay inside the limits.** No production routes, real credentials, real user data, or writes to shared or production systems. Use fixtures or a scratch copy. If it needs more than that, ask first.
6. **Surface the state.** After each action, or each variant switch, show what changed.
7. **Be honest about what it cannot show.** List every mock and simplification and say which conclusions they do not support. Keep any failure that changes the conclusion instead of tidying it away.
## 4. Finish: keep the answer, not the code
1. **Report** the question, how to run it, what you observed (failures included), the verdict, and its limits.
2. **Record the answer** where the next reader will look: the issue, spec, plan or decision log, or the commit message. One line is enough: the question, the verdict, the reason. If there is no such place, put a notes file next to the prototype. If the user is not around to give the verdict, leave a clearly marked placeholder for it.
3. **Hand over behaviours, not code.** The cases the prototype validated become the list of tests or acceptance checks for the real build, which starts fresh and test first. The prototype may be read as a reference. It is not cleaned up and shipped.
4. **Dispose of it, with the user's say-so.** Offer two options: delete it, or keep it on a throwaway branch that is never merged, if they want the prototype itself as a record. Delete only the files you created for it, and only after the answer is recorded and the user agrees. Never delete anything that is not part of the prototype. Do not push or merge the branch unless asked, and stage the prototype's files by path, never everything at once.
A failed premise is a result. If the prototype shows the idea does not work, say so with the evidence and stop. Do not invent implementation work to rescue it.
## Example
The user says: "We're adding refunds. I'm not sure the order states hold up."
- **Question:** "Can the order model (placed, paid, shipped, refunded) reach a state where a refund is issued twice, or stock is restocked for an item that never shipped?"
- **Kind:** logic. The core is one function that takes a state and an event and returns the next state. The shell is one HTML file with a button per event, the full state shown after every click, and three walkthroughs: refund twice, refund after a partial shipment, cancel while payment is pending.
- **Run:** the partial-shipment walkthrough restocks an item that never left the warehouse, so the model has a hole. The pending-payment walkthrough ends in a state whose right answer is a policy decision, so the agent asks: "If a customer cancels while payment is pending, is that a refund or just a void?"
- **Finish:** the answers are recorded in the plan, the three walkthroughs become three failing tests for the real implementation, and the agent asks whether to delete the prototype or keep it on a branch.
## Signs it is drifting
- You are adding tests, abstractions or error handling.
- It is answering a second question.
- You are polishing the look of a probe that only needs to work.
- Someone proposes shipping it. The answer ships. Rebuild the code.
- "It runs" is being treated as the result. The result is what it showed.
The second audit
What we found in the sources
It keeps the shape of the version most others copy (mattpocock/skills): write the question, build the cheapest artifact that answers it, keep the answer and let the code go. It adds a third kind of probe for library, API and approach questions, a limits-and-honesty rule, and a safer finish. Every source below was read at the commit the auditor recorded. Nothing was taken from a source without a permissive license.
What each source contributed
- mattpocock/skills ↗ · Primary basis · MIT
The framing (a prototype is throwaway code that answers a question and the question decides the shape), the two branches (a logic or state-model probe and a set of UI variants) with their one-line designs, the rules for every prototype (throwaway and clearly marked, one command to run, no persistence by default, skip the polish, surface the state), the default-by-surrounding-code rule when the question is ambiguous, and the idea of keeping the answer and a throwaway branch while main keeps only the decision. The LOGIC.md and UI.md files it points to were not in the audited bundle, so the logic and UI designs were written from its one-line descriptions.
- nyelonong/galdr ↗ · Added ideas · MIT
Writing the question down before any code and refusing to prototype without one, the split between a pure core and a throwaway shell, putting every variant of a comparison behind one switch so they run under identical conditions, restarting when the question changes shape, and handing over validated behaviours as the test list rather than the prototype's code.
- maajix/Plumbline ↗ · Added ideas · MIT
The question stated as what is being decided and which answer would change the plan, running the scenarios yourself first and treating the answer as what the state did, putting a product-level surprise to the user as one concrete situation instead of "does this look right", leaving the prototype branch unmerged, not pushing it without being asked, and staging files by path.
- mascah/skills ↗ · Added ideas · MIT
Settling question, limits and observable evidence before building, staying inside authorized bounds (no production routes, credentials or data writes), running representative cases including failure conditions, stating the mocks and what they cannot establish, preserving failure evidence that changes the conclusion, the report shape (question, how to run, observation, verdict, limits), not promoting a promising prototype automatically, and abandoning a failed premise with the evidence.
- rengwu/wayfinder-maps ↗ · Added ideas · MIT
The point that the answer is the only part worth keeping, leaving a placeholder for the verdict when the user is not around, the allowance that a logic probe can be a small terminal program, and run-command examples beyond the JavaScript ones.
What changed
- The description now lists the three kinds of question, the phrases that should trigger it ("prototype this", "spike it", "mock it up", "try both approaches") and a "not for" clause. The primary's description is two sentences and mentions only logic and UI.
- Rewritten as one self-contained file. The logic and UI designs the primary delegates to LOGIC.md and UI.md are now short sections; since those files were not available, they were written fresh from the one-line descriptions in the sources.
- Added a third kind, the feasibility probe (does a library, API or approach behave as needed; is X or Y better), from galdr and mascah. The primary covers only logic and UI.
- The finish no longer tells the agent to commit the prototype to a branch and leave a pointer on "the implementation issue", which assumes a git host and an issue tracker. It now says to record the answer where the next reader will look, offers the branch as an option to the user, and deletes only files the agent created, only after the answer is recorded and the user agrees.
- Run-command examples are generic (a task runner, python, make, cargo) instead of pnpm and bun.
- Added a worked example and a short list of signs that a prototype is drifting into production code.
Problems found in the sources
- mattpocock/skills: Sends the reader to LOGIC.md and UI.md, which are not part of the SKILL.md, so a lone copy has dangling references to the two branches that hold the actual designs. The description names logic and UI questions only and has no "not for" clause. The last rule tells the agent to commit the prototype to a branch and leave a pointer on the implementation issue without asking the user, and assumes an issue tracker exists.
- rengwu/wayfinder-maps: Still links LOGIC.md and UI.md, which are not in the folder. Ends by telling the agent to delete the prototype or fold it into the real code, without saying to delete only what it created or to confirm first (unclear whether that was intended).
- nyelonong/galdr: Written for its own toolchain: it names plan, tdd, shape and continue skills, a memory-progress.md file and a project "Iron Law", none of which a lone copy has, and it sets disable-model-invocation so it never triggers on its own. It lists three conditions for its exemption and then says "if either stops being true". It allows a prototypes/ graveyard directory in the working tree while also saying the prototype must not stay in the tree as active code (unclear how those fit together).
- maajix/Plumbline: Depends on its own flow (shape, write-spec, effort, cut-slices, hold-the-line, cold-read), on a ${CLAUDE_PLUGIN_ROOT} file path, and on LOGIC.md and UI.md, so it cannot be used alone. The file credits Matt Pocock's skill as its origin. Its git guidance (stage by path, ask before pushing) is sound.
- mascah/skills: Points to references/discipline.md, which is not in the folder, and to discovery, spec and ADR documents that only exist in its own project. The description has no trigger phrases and no "not for" clause.
- panda850819/pandastack: The description opens with a sentence about overriding a production-build reflex before saying what the skill does, which is hard to match against a request. Its frontmatter uses host-specific keys (reads, writes, domain, classification). It refers to the skills grill, ui and wayfinder and to LOGIC.md and UI.md, none of which are present.
What was dropped
- galdr's ties to its own plan, tdd, shape and continue skills, its memory-progress.md decision-line format, its "Iron Law exemption" section, the Go build-tag and Rust feature-flag specifics, and its disable-model-invocation setting.
- Plumbline's effort, shape, write-spec and cut-slices flow, its worktree command sequence, its ticket-lifecycle.md commit convention, and its rule that UI prototypes never run inside an effort.
- pandastack's host-specific frontmatter keys and its converge mode, which lives in a file that was not fetched.
- mascah's pointer to references/discipline.md and its discovery, spec and ADR targets.
Read but not used (4)
- the-inconvenience-store/skills: Byte-identical to mattpocock/skills (same SHA-256).
- Bossmann007/cursor-kit: The mattpocock/skills text with punctuation changed (em dashes replaced by commas, colons and brackets); the diff shows no change of content.
- panda850819/pandastack: Same structure and five of the same rules as mattpocock/skills, with the logic branch described as a terminal program. It adds a "converge" mode of repeated UI rounds, which is defined in UI.md, a file that was not fetched, so nothing distinct was taken.
- RollRollRoll/agent-toolkit: A Chinese translation of the mattpocock/skills text: the same two branches and the same six rules, with links pointing to references/logic.md and references/ui.md.
Left out for license (1)
No license is declared on these, so nothing was taken from them: lukekeith/builder.
Same text, wherever you work
Use it where you work
Copy the folder into your skills directory, then ask for the job or type its start command.
- Download
SKILL.mdwith the button above, and put it in a folder namedprototype. - Zip the folder.
- In Claude, open Settings → Skills and upload the zip.
SKILL.md is plain Markdown. Copy the text and paste it as the system prompt or the first message. It will not trigger by itself there; you start it.