shadcn-prototype
Use this skill when the user wants to explore design options for a shadcn/ui interface before committing to one — building 2-4 radically different UI variations on a single throwaway route, switchable via a URL search param + a floating bottom bar. Trigger phrases "let me see some options", "show me variations", "I want to play with the layout first", "prototype this", "try a few designs", "build a few mockups", "before I commit", "what should this look like", "explore the UI", "what are some ways to lay this out". Also use proactively when the user describes a new screen / page / component that has more than one reasonable layout and the right answer isn't obvious from spec alone. Different from `shadcn-components` (which assumes the design decision is made — you're adding the third button) and from a normal page build (which commits to one design). The shadcn-prototype workflow is "let me ship 3 versions side-by-side, you click through, pick one, we delete the others."
What this skill does
# shadcn-prototype
Build a throwaway prototype to explore 2-4 radically different UI variations side-by-side **before** committing to one. The user clicks through, picks a winner, the chosen variant gets promoted into real code and the rest get deleted.
This is the upstream of `shadcn-components` / `shadcn-forms` / `shadcn-data-tables`. Those skills assume the design decision is made — you're filling in a known shape. This skill is *how the shape gets decided* when more than one is plausible.
## How shadcn-prototype works
The skill follows the **prototype protocol** (canonical at `docs/protocols/prototype.md` at the marketplace root; a copy ships with this plugin at `${CLAUDE_PLUGIN_ROOT}/protocols/prototype.md`). Read that file first. The protocol owns the mechanic:
- Pick a branch — UI vs Logic. shadcn-prototype is almost always **UI branch**.
- Six universal rules — throwaway-marked, one command to run, no persistence, skip the polish, surface the state, delete or absorb when done.
- Capture the answer — commit message, ADR, or `NOTES.md` before deletion.
This skill is the **shadcn-specific layering** on top of that protocol — variant-switching primitives, routing conventions, scratch persistence idioms, and concrete examples.
## When this skill is the right fit
- User describes a new screen / page / feature where >1 layout makes sense
- User says "what should this look like" or asks to mock something up
- An existing screen needs a redesign and the team isn't aligned on direction
- Design and engineering disagree on density / hierarchy / flow
When this skill is *not* the right fit:
- The team already has a Figma mock — just implement it; use `shadcn-components` directly
- The decision is trivial (button color, spacing tweak) — just ship and revise
- The question is logic, not visual — that's a different prototype shape (see `docs/protocols/prototype.md` LOGIC branch)
- A real prototype already exists in the codebase — extend rather than duplicate
## Variant-switching primitive — URL search param + floating switcher
The protocol calls for variant switching via "a URL search param + a floating bottom bar." For shadcn projects, the canonical implementation:
```tsx
// app/_prototypes/<slug>/page.tsx (Next.js App Router)
// or src/prototypes/<slug>/index.tsx (Vite + React Router)
"use client"
import { useSearchParams, useRouter, usePathname } from "next/navigation"
import { Button } from "@/components/ui/button"
import { Card } from "@/components/ui/card"
import { cn } from "@/lib/utils"
const VARIANTS = [
{ id: "single", label: "Single page", note: "Everything visible, no navigation" },
{ id: "wizard", label: "Step-by-step wizard", note: "One section per screen, next/back" },
{ id: "hybrid", label: "Collapsible single", note: "Single page, collapsible sections, skip-to-end" },
] as const
type VariantId = typeof VARIANTS[number]["id"]
export default function CheckoutPrototype() {
const sp = useSearchParams()
const router = useRouter()
const pathname = usePathname()
const active = (sp.get("v") as VariantId) || "single"
const switchTo = (id: VariantId) => {
const params = new URLSearchParams(sp)
params.set("v", id)
router.replace(`${pathname}?${params.toString()}`)
}
return (
<div className="min-h-screen pb-24">
{active === "single" && <SingleVariant />}
{active === "wizard" && <WizardVariant />}
{active === "hybrid" && <HybridVariant />}
<VariantSwitcher active={active} onSwitch={switchTo} />
</div>
)
}
function VariantSwitcher({ active, onSwitch }: { active: VariantId; onSwitch: (id: VariantId) => void }) {
return (
<Card className="fixed bottom-4 left-1/2 -translate-x-1/2 flex items-center gap-2 p-2 shadow-lg">
<span className="text-xs text-muted-foreground px-2">Prototype variants</span>
{VARIANTS.map(v => (
<Button
key={v.id}
size="sm"
variant={active === v.id ? "default" : "ghost"}
onClick={() => onSwitch(v.id)}
title={v.note}
>
{v.label}
</Button>
))}
</Card>
)
}
```
**Why URL search param, not React state?** Shareability. A `?v=wizard` URL can be pasted into Slack or a comment. State doesn't persist across reloads, which kills the "show me again" feedback loop.
**Why a `<Card>` floating bar, not `<Tabs>`?** Tabs imply a hierarchical relationship; prototype variants are mutually exclusive alternatives the user is choosing between. The floating bar reads as a chooser, not a navigation pattern.
**Why `Button variant="ghost" vs "default"`?** Visual signal of which variant is active without needing radio-style affordance.
## Routing conventions per framework
| Framework | Route convention | Why |
|---|---|---|
| **Next.js App Router** | `app/_prototypes/<slug>/page.tsx` | The `_` prefix doesn't actually hide it from routing in App Router, but it signals "scratch" to humans scanning the tree. Cleaner: use a `(prototypes)` route group so the URL is `/<slug>` but the file lives under `app/(prototypes)/<slug>/`. |
| **Next.js Pages Router** | `pages/prototypes/<slug>.tsx` | Standard nested routing. |
| **Vite + React Router** | A registered `<Route path="/prototypes/:slug" element={<...>} />` in your router config. File at `src/prototypes/<slug>.tsx`. |
| **Tanstack Router** | `src/routes/prototypes/<slug>.tsx` (file-based). |
| **Remix** | `app/routes/prototypes.<slug>.tsx`. |
Pick whichever matches the project's existing convention. **Do not invent a new top-level routing structure for prototypes** — that's the prototype tail wagging the production dog.
## When to use `cva()` vs separate variant components
shadcn-style codebases often use `cva()` (`class-variance-authority`) to encode variants of a single component. For prototypes:
**Use separate components** (`<SingleVariant />`, `<WizardVariant />`, `<HybridVariant />`) when:
- The variants differ in **structure** — different component trees, different flows, different state machines
- Each variant might be the seed of a real implementation later — having them in separate files makes it easy to delete the losers and promote the winner
**Use `cva()` within one component** when:
- The variants differ only in **styling** — density, hierarchy, spacing
- The structure is shared and you're A/B/C-testing visual treatment
For the vast majority of prototypes that get to this skill, the answer is **separate components** — if the differences were only styling, the question probably wasn't worth a prototype.
## Scratch persistence — when the prototype needs data
The protocol's rule 3 says "no persistence by default. State lives in memory." For shadcn prototypes that need *some* data:
- **Hard-coded fixtures** in a `fixtures.ts` next to the prototype. 90% of cases.
- **In-memory store via Zustand or Jotai** with no persistence middleware. Resets on every reload — exactly what you want for the "is the flow right" question.
- **`localStorage` only if the question is specifically about persistence** (e.g., "should this remember the user's draft between sessions?"). Name the key with a clear `PROTOTYPE_` prefix so it's easy to clean up: `localStorage.setItem("PROTOTYPE_checkout_v2_draft", ...)`.
- **A real database — almost never.** If the prototype's question genuinely needs a DB, it's no longer a prototype.
## Three concrete examples
### Example 1: Checkout flow density
User: *"Should this checkout be a single page or a wizard?"*
```
app/(prototypes)/checkout-v2/
├── page.tsx ← orchestrator + VariantSwitcher
├── variants/
│ ├── SingleVariant.tsx ← everything on one screen
│ ├── WizardVariant.tsx ← step-by-step with next/back
│ └── HybridVariant.tsx ← single page with collapsibles
├── fixtures.ts ← hard-coded cart, user, payment methods
└── NOTES.md ← question + decision after the prototype
```
Three real components implementing the tRelated in Design
contribute
IncludedLocal-only OSS contribution command center. Auto-refreshes the user's in-flight PR and issue state on invoke so conversations start with full context — no need to brief Claude on what's in flight. Helps the user find issues to contribute to on GitHub, builds per-repo dossiers of what each upstream expects (CLA, DCO, branch convention, AI policy, draft-first, review bots, issue templates), runs deterministic gates before any external action so AI-assisted contributions don't reach maintainers as slop. State is markdown-only: candidate files at ~/.contribute-system/candidates/, repo dossiers at ~/.contribute-system/research/, append-only event log at ~/.contribute-system/log.jsonl. No database, no cloud calls. Use when the user asks about their PRs / issues / contributions, wants to find new work to take on, claim an issue, build/refresh a repo's dossier, or draft a Design Issue or PR. Trigger with "/contribute", "what's my PR status", "find a contribution", "claim issue X", "draft a Design Issue for Y", "refresh dossier for Z".
architectural-analysis
IncludedUser-triggered deep architectural analysis of a codebase or scoped subtree across eight modes — information architecture, data flow, integration points, UI surfaces, interaction patterns, data model, control flow, and failure modes. This skill should be used when the user asks to "diagram this codebase," "map the architecture," "show the data flow," "give me an ERD," "trace control flow," "find the integration points," "verify the layout pattern," "audit the UX architecture," or any similar request whose primary deliverable is mermaid diagrams plus cited reports under docs/architecture/. Dispatches haiku/sonnet sub-agents in parallel for per-mode exploration, then verifies every citation mechanically before any node lands in a diagram. Not for one-off prose explanations of code (use code-explanation) or for high-level system design from scratch (use system-design).
mcp
IncludedModel Context Protocol (MCP) server development and tool management. Languages: Python, TypeScript. Capabilities: build MCP servers, integrate external APIs, discover/execute MCP tools, manage multi-server configs, design agent-centric tools. Actions: create, build, integrate, discover, execute, configure MCP servers/tools. Keywords: MCP, Model Context Protocol, MCP server, MCP tool, stdio transport, SSE transport, tool discovery, resource provider, prompt template, external API integration, Gemini CLI MCP, Claude MCP, agent tools, tool execution, server config. Use when: building MCP servers, integrating external APIs as MCP tools, discovering available MCP tools, executing MCP capabilities, configuring multi-server setups, designing tools for AI agents.
react-native-skia
IncludedDesign, build, debug, and optimise high-polish animated graphics in React Native or Expo using @shopify/react-native-skia, Reanimated, and Gesture Handler. Use when the user wants canvas-driven UI, shaders, paths, rich text, image filters, sprite fields, Skottie, video frames, snapshots, web CanvasKit setup, or performance tuning for custom motion-heavy elements such as loaders, hero art, cards, charts, progress indicators, particle systems, or gesture-driven surfaces. Also use when the user asks for fluid, glow, glass, blob, parallax, 60fps/120fps, or GPU-friendly animated effects in React Native, even if they do not explicitly say "Skia". Do not use for ordinary form/layout work with standard views.
plaid
IncludedProduct Led AI Development — guides founders from idea to launched product. Six capabilities: Idea (discover a product idea), Validate (pressure-test the idea against fatal flaws, problem reality, competition, and 2-week MVP feasibility), Plan (vision intake + document generation), Design (translate image references into a design.md spec), Launch (go-to-market strategy), and Build (roadmap execution). Use when someone says "PLAID", "plaid idea", "help me find an idea", "product idea", "idea from my business", "idea from my expertise", "plaid validate", "validate my idea", "pressure-test", "is this idea good", "find fatal flaws", "validate the problem", "plan a product", "define my vision", "generate a PRD", "product strategy", "plaid design", "design from image", "translate image to design", "create design.md", "extract design tokens", "plaid launch", "go-to-market", "launch plan", "GTM strategy", "launch playbook", "plaid build", "build the app", "start building", or "execute the roadmap".
nextjs-framer-motion-animations
IncludedAdds production-safe Motion for React or Framer Motion animations to Next.js apps, including reveal, hover and tap micro-interactions, whileInView, stagger, AnimatePresence, layout and layoutId transitions, reorder, scroll-linked UI, and lightweight route-content transitions. Use when the user asks to add, refactor, or debug Motion or Framer Motion in App Router or Pages Router codebases, especially around server/client boundaries, reduced motion, LazyMotion, bundle size, hydration, or route transitions. Avoid for GSAP-style timelines, WebGL or 3D scenes, heavy scroll storytelling, or CSS-only effects unless Motion is explicitly requested.