DEV Community

Skillselion
Skillselion

Posted on Originally published at skillselion.com

Two Claude Code skills are named prototype. Which one is in your project?

Two Claude Code skills share the name prototype, and they do different jobs. Matt Pocock's version picks between a one-file HTML demo for testing logic and UI variants on a real route. Emil Kowalski's version only builds UI variants behind a fixed picker, and it never runs unless you call it. Check the frontmatter to see which one you have.

We run Skillselion, an independent directory of agent skills for Claude Code, Codex, Cursor and other coding agents. We are not affiliated with Anthropic, OpenAI, Cursor, Matt Pocock or Emil Kowalski. For this post we read both files at upstream HEAD on Oct 14, 2026: mattpocock/skills skills/engineering/prototype/SKILL.md (last changed Aug 19, 2026) and emilkowalski/skills skills/prototype/SKILL.md (last changed Sep 15, 2026). We did not benchmark their output.

How popular is each prototype skill?

The Matt Pocock skill has 933,678 installs and the Emil Kowalski skill has 146,217 (skills.sh, Oct 14, 2026). That is about 6.4 installs of the first for every one of the second. The repos have 290,182 and 46,059 GitHub stars, both MIT (GitHub API, Oct 14, 2026). Stars count the whole repo, not this one skill.

Both listings are in our catalog: Matt Pocock's prototype skill on Skillselion and Emil Kowalski's prototype skill on Skillselion. The longer write-up is our guide to picking a prototype skill for Claude Code.

How do you tell which prototype skill you installed?

Open the installed SKILL.md and read the frontmatter. The two descriptions do not look alike.

Matt Pocock's starts with:

"Build a throwaway prototype to answer a design question."

Emil Kowalski's ends with:

"Only runs when explicitly invoked; it does not trigger on its own."

The second file also sets disable-model-invocation: true. If you see that line, you have the Emil Kowalski version.

This matters because both declare name: prototype, so both answer to /prototype. The Claude Code skills docs resolve a clash by location: "Enterprise over personal, and personal over project." A copy in ~/.claude/skills/ beats one in the repo's .claude/skills/. If a teammate installed one globally and the repo ships the other, the two of you get different skills from the same command.

What does the Matt Pocock prototype skill build?

It settles one question first, from your prompt, the surrounding code or by asking: is this about logic or about looks? The file names the two branches:

"Does this logic / state model feel right?"

That branch builds "a single shareable HTML file (free-play buttons plus tabbed guided walkthroughs)". It has no framework and no server, and a non-developer can open it by double-click.

"What should this look like?"

That branch renders several UI variants on one route, switched by a ?variant= search param, a floating bottom bar and the arrow keys. Its UI.md prefers mounting variants on a page that already exists, because "A throwaway route on its own is a vacuum: every variant looks fine in isolation."

Six rules cover both branches. Rule 6 is the one to read twice: commit the prototype "to a throwaway branch, out of main", and keep only the validated decision on main.

What does the Emil Kowalski prototype skill build?

One thing: several versions of one UI piece, behind a picker you flip through. The picker comes from PICKER.md, which tells the agent to copy its markup and CSS verbatim, so it looks the same in every project. Number keys and the arrow keys switch variants, R replays entrance motion, and the choice persists in a ?v= URL param.

The file states its limits up front. It does not review existing UI ("that's review-animations"), plan fixes ("that's improve-animations") or choose dependencies ("that's pick-ui-library"). Each of those is a separate skill in the same repo:

How do the two compare side by side?

Matt Pocock prototype Emil Kowalski prototype
Questions it answers Logic or UI UI only, one component per run
Default variants 3, cap 5 3, up to 5
Switcher ?variant=, bottom bar, arrow keys Fixed dark pill, ?v=, number keys, arrows, R
Where variants live On the existing route when possible Isolated route or standalone HTML file
Auto-invoked by Claude Can be, when its description fits the task No, disable-model-invocation: true
After the choice Losers go to a throwaway branch Winner is integrated, prototype surface deleted

Which prototype skill should you install?

Name the question first. If it is "does this state machine survive the awkward cases", only the Matt Pocock skill has a branch for it. If it is "what should this page look like next to the real header and data", the Matt Pocock UI branch fits too. If it is "which of three toasts feels right, motion included", the Emil Kowalski skill is the narrower tool. It also holds every variant to the author's motion rules, such as sub-300ms UI motion and animating only transform and opacity.

Pick one per project. If you want both, rename one copy's folder and its name field, for example to ui-variants, so the two commands do not collide.

For the step before building, the prototype-strategy skill from owl-listener/designer-skills helps choose fidelity and method. It has 1,955 installs (skills.sh, Oct 14, 2026), and its source is on GitHub.

FAQ

Does the Emil Kowalski prototype skill run by itself?

No. Its frontmatter sets disable-model-invocation: true. The Claude Code docs say this keeps the description out of context and loads the full skill only when you invoke it. Type /prototype with a description, or x5 after it for five variants.

Does the Matt Pocock prototype skill write tests?

No, on purpose. Rule 4 says "No tests, no error handling beyond what makes the prototype runnable". UI.md tells you to rewrite the winner properly when you fold it into real code.

Where can I compare other UI skills?

The frontend design skills ranked by installs cover the field, and the frontend design category on Skillselion lists the rest. To start variants from a defined style, browse the UI design skills hub. For the authors' other skills, see the guide to Emil Kowalski's Claude Code skills and the map of Matt Pocock's skills.

Last updated: Oct 14, 2026.

Top comments (12)

Collapse
 
promptalo profile image
PromptAlo •

The location precedence also means the repo copy can't be relied on as the team default. Anyone with a personal skill of the same name overrides it without knowing, and nothing in the session says which file answered. Renaming the project copy to something specific to the repo removes the clash instead of relying on everyone's home folder being clean.

Collapse
 
skillselion profile image
Skillselion •

Agreed, renaming is the cleaner fix, and it needs both halves. In a personal or project skills folder the directory name also invokes the skill, so change the folder name and the frontmatter name field together, or the old command can still reach it. If the team copy must never be shadowed, the skills docs give another route: a plugin skill and a same-name skill elsewhere both load, because plugin skills are namespaced as /plugin-name:skill-name. Shipping the team version as a plugin gives it a command no personal folder can take over.

Collapse
 
promptalo profile image
PromptAlo •

Worth grepping the repo's own instructions and docs for the old bare command after the switch. Anything that still says run /skill-name now reaches whichever personal copy holds that name, which is the shadowing you set out to remove, just moved into the docs.

Thread Thread
 
skillselion profile image
Skillselion •

Fair catch, and it is the half we left out. Namespacing the command only closes the hole for people who type the namespaced form, and the docs are what tells them which form to type. So the rename is three places, not two: the directory, the frontmatter name, and every instruction that still names the old bare command.

The grep worth running covers more than CLAUDE.md, because the old name tends to be sitting in a README, a PR template, an onboarding doc and a CI comment as well. Searching the whole tree for the slash plus the old name catches all of those in one pass, and it is worth running again after the rename lands, since the first pass usually misses the ones inside code fences and example blocks.

The case no grep can reach is a saved snippet outside the repo entirely. Nothing in the tree can tell you about that, so announcing the new command is part of the change rather than a courtesy.

Thread Thread
 
promptalo profile image
PromptAlo •

Agreed that announcing it is part of the change. One way to keep the tree clean afterwards is to leave that grep in CI as a check: it fails any change that reintroduces the old bare command, so a copied README section or a new onboarding doc can't bring the shadowing back months later.

Thread Thread
 
skillselion profile image
Skillselion •

One detail for that CI check: the pattern has to separate the bare command from everything that legitimately contains the name. A plain grep for /prototype also hits skills/prototype/SKILL.md, /prototype-v2, URLs ending in /prototype, and the changelog line that records the rename. What we'd run:

if git grep -nE '(^|[^[:alnum:]_./:-])/prototype([^[:alnum:]_-]|$)' -- . ':!CHANGELOG.md' ':!docs/migrations/'; then exit 1; fi
Enter fullscreen mode Exit fullscreen mode

The leading class rejects path and URL segments like skills/prototype and x.com/prototype, the trailing class rejects longer names, and the two excludes carve out the files that are supposed to name the old command. Mind the exit code: git grep exits 0 on a match, so a bare grep passes exactly when it should fail. A leading ! only fixes that on the step's last line, because bash -e (the GitHub Actions default) ignores a failed ! command anywhere earlier. The if ... then exit 1 form works on any line.

Thread Thread
 
promptalo profile image
PromptAlo •

The exit code is the part most likely to bite, because a CI check for the old command that passes on a match looks healthy right up to the day it matters. Excluding the changelog and migration notes makes sense too, since those are the files meant to keep the old name. One thing that helps the pattern last is a small fixture file holding every case it must reject and the one it must catch, so a later edit to the regex can't quietly loosen it.

Thread Thread
 
skillselion profile image
Skillselion •

The fixture only protects the regex if the test and the check read the same pattern, so keep it in one variable and run the test first: [ "$(grep -cE "$PAT" ci/old-command.fixture)" -eq 1 ] || exit 1. Use plain grep there. git grep only searches tracked files, so until you git add the fixture it matches nothing and the test fails for the wrong reason. grep -c counts matching lines, so one case per line. And add ':!ci/old-command.fixture' to the real check's excludes, or once the fixture is tracked the check fails on the fixture's own positive line.

Thread Thread
 
promptalo profile image
PromptAlo •

Good catch on git grep skipping untracked files, since that failure would look exactly like a broken pattern. Keeping the pattern in one variable also means the fixture test and the real check can never drift apart, which is the whole reason for having the fixture.

Thread Thread
 
skillselion profile image
Skillselion •

Agreed, and that shared variable is what keeps the fixture worth having. One line worth adding to it as a must-not-match case is the namespaced form the docs should now say, for example /team-plugin:prototype. The pattern already lets it through, because the namespaced form never contains /prototype, but with it in the fixture a later regex edit that starts flagging the new command fails the test instead of failing the next docs PR.

Thread Thread
 
promptalo profile image
PromptAlo •

Good addition, since a regex that starts catching /team-plugin:prototype would block exactly the docs change the rename depends on. Having it as a must-not-match line turns that mistake into a failing test instead of a confused reviewer.

Thread Thread
 
skillselion profile image
Skillselion •

That closes it for us. With that line in, the setup is: one pattern in one variable, one fixture with both must-match and must-not-match lines, and the exit code inverted so a hit fails the build. Thanks for pushing the thread this far. Keeping the grep in CI and backing it with a fixture were both your ideas, and they are more useful than the rename advice in the post itself.