Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Shadcn Components

ASecurity

Use when building or editing shadcn/ui components, mapping Base UI vs Radix vs React Aria APIs, or choosing a composition pattern (render vs asChild vs trigger wrapper).

29 stars
0 votes
0 copies
1 views
Added 5/28/2026
ai-agentsreactnextjsapi

Works with

cliapimcp

Security Analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned 9/29/2026

$npx -y skills add fusengine/agents --skill shadcn-components --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Shadcn Components?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Shadcn Components
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/fusengine-shadcn-components/badge)](https://www.skillsdirectory.com/skills/fusengine-shadcn-components)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: shadcn-components
description: "Use when building or editing shadcn/ui components, mapping Base UI vs Radix vs React Aria APIs, or choosing a composition pattern (render vs asChild vs trigger wrapper)."
versions:
  shadcn-ui: "4.x"
  radix-ui: "1.x"
  base-ui: "1.x"
user-invocable: true
allowed-tools: Read, Write, Edit, Glob, Grep, Task, mcp__shadcn__search_items_in_registries, mcp__shadcn__view_items_in_registries, mcp__shadcn__get_item_examples_from_registries, mcp__shadcn__get_add_command_for_items
references: references/radix-components.md, references/baseui-components.md, references/templates/dialog-example.md
related-skills: shadcn-detection, shadcn-registries
---

<objective>
Documents component patterns for shadcn/ui on its three bases — Base UI (default since July 2026), Radix and React Aria — API differences, mapping between primitives (Dialog/Select/Tooltip/Accordion/Popover/Menu/Combobox), per-base component availability, and the three composition patterns (`render` for Base UI, `asChild` for Radix, trigger-wrapper children for React Aria).

Requires detecting the project's primitive first (`shadcn-detection`) and consulting the shadcn MCP for registry source instead of hand-writing component internals.
</objective>

# shadcn Components

## Agent Workflow (MANDATORY)

Before component work, spawn agents in parallel, one `Agent` call each with a `name`:

1. **fuse-ai-pilot:explore-codebase** - Find existing components
2. **fuse-ai-pilot:research-expert** - Verify component APIs via Context7
3. **mcp__shadcn__search_items_in_registries** - Search available components

After: Run **fuse-ai-pilot:sniper** for validation.

---

## Overview

| Feature | Description |
|---------|-------------|
| **Base UI primitives** | Default base for new projects since 2026-07-02 (`base-*` styles, `@base-ui/react`); `init --defaults` = Next.js template + `nova` preset on the `base` base = `base-nova` |
| **Radix primitives** | Original base (2023), still fully supported (`radix-*` styles, unified `radix-ui` package); `init -b radix` |
| **React Aria primitives** | Third base since 2026-07-17 (`aria-*` styles, `react-aria-components`); `init -b aria` |
| **Component mapping** | Same shadcn wrapper names for Base UI and Radix; React Aria wrappers differ (see below) |
| **API differences** | `render` vs `asChild` vs trigger wrapper, part naming, data attributes |
| **`cn` import** | Components import `cn` from the `cn` package (Sept 2026); `lib/utils.ts` is `export { cn } from "cn"` |

Get base-specific docs, examples and API links from the CLI: `{runner} shadcn@latest docs dialog --base aria` (`--base base|radix|aria`, defaults to the project base). Component pages: `/docs/components/{base|radix|aria}/<name>`, each with a Composition tree.

---

## Critical Rules

1. **ALWAYS detect primitive** before component work (shadcn-detection)
2. **ALWAYS consult MCP** before adding any component
3. **NEVER mix** Base UI, Radix and React Aria APIs in same component
4. **MATCH composition** pattern to detected primitive
5. **USE registry source** as truth, not manual code

---

## Architecture

```
components/ui/
├── dialog.tsx          # Adapted to detected primitive
├── select.tsx
├── accordion.tsx
└── ...
```

-> See [dialog-example.md](references/templates/dialog-example.md) for complete component

---

## MCP Usage (MANDATORY)

ALWAYS consult shadcn MCP before adding components:

```
mcp__shadcn__search_items_in_registries -> find component
mcp__shadcn__view_items_in_registries   -> view source
mcp__shadcn__get_add_command_for_items  -> get install command
```

---

## Component Mapping Table

Primitive parts used inside `components/ui/*.tsx` (registry `*-nova` sources, `ui.shadcn.com/r/styles/<style>/<name>.json`):

| Component | Radix Part | Base UI Part | React Aria Part |
|-----------|-----------|--------------|-----------------|
| Dialog content | `Dialog.Content` | `Dialog.Popup` | `Modal` > `Dialog` |
| Dialog overlay | `Dialog.Overlay` | `Dialog.Backdrop` | `ModalOverlay` |
| Select | `Select.Content` | `Select.Positioner` + `Select.Popup` (+ `Select.List`) | `Select` + `Popover` > `ListBox` |
| Tooltip | `Tooltip.Content` | `Tooltip.Positioner` + `Tooltip.Popup` | `TooltipTrigger` > `Tooltip` |
| Accordion | `Accordion.Content` | `Accordion.Panel` | `DisclosureGroup` > `Disclosure` > `DisclosurePanel` |
| Popover | `Popover.Content` | `Popover.Positioner` + `Popover.Popup` | `DialogTrigger` > `Popover` |
| Menu | `DropdownMenu.Content` | `Menu.Positioner` + `Menu.Popup` | `MenuTrigger` > `Popover` > `Menu` |
| Combobox | none (uses `@base-ui/react` Combobox) | `Combobox.*` | `ComboBox` + `Popover` > `ListBox` |

Wrapper API at call sites (`@/components/ui/*`):

| Wrapper usage | Base UI | Radix | React Aria |
|---------------|---------|-------|------------|
| Dialog | `Dialog > DialogTrigger + DialogContent` | same as Base UI | `DialogTrigger > Button + Dialog` (no `DialogContent`) |
| Popover / Tooltip / DropdownMenu | `X > XTrigger + XContent` | same | `XTrigger > Button + X` (e.g. `DropdownMenuTrigger > Button + DropdownMenu`) |
| Accordion | `defaultValue={["a"]}`, `multiple` | `type="single" collapsible defaultValue="a"`, `type="multiple"` | `defaultExpandedKeys={["a"]}`, `allowsMultipleExpanded`, items use `id` |
| Select | `items` prop on `Select`, `SelectItem value` | `SelectItem value` | `placeholder` on `Select`, `SelectItem id` |
| Combobox | `items` + `ComboboxList` render function | same as Base UI | `ComboboxList` children, `renderEmptyState`, `ComboboxItem id` |
| Events / state | `onClick`, `disabled`, `open`/`onOpenChange` | same | `onPress`, `isDisabled`, `isOpen`/`onOpenChange` |
| Raw data attrs | `data-open`, `data-starting-style`, `data-side` | `data-state="open"`, `data-side` | `data-entering`/`data-exiting`, `data-placement`, `data-focused`, `data-pressed` |

Shared `data-open:` / `data-closed:` / `data-checked:` Tailwind variants (from `shadcn/tailwind.css`) match both `[data-state=...]` and `[data-open]`.

## Component Availability per Base

| Component | Base UI | Radix | React Aria |
|-----------|---------|-------|------------|
| Toast (`@base-ui/react/toast`, `toast.add()`) | yes (July 2026) | no: use Sonner | no: use Sonner |
| Sonner | registry item exists; docs route to Toast | yes | yes |
| Menubar, Navigation Menu | yes | yes | no (`r/styles/aria-nova/{menubar,navigation-menu}.json` → 404) |
| Questionnaire (styled over `@shadcn/react/questionnaire`) | yes | yes | yes |
| MessageScroller, Message, Bubble, Attachment, Marker (chat, June 2026) | yes | yes | yes (docs pages exist) |
| Blocks (`login-01`, sidebar, dashboard...) | yes | yes | yes (e.g. `r/styles/aria-nova/login-01.json`); `add` picks the project base |

Forms (/docs/forms): every guide builds on `Field`, `FieldLabel`, `FieldDescription`, `FieldError`, `FieldGroup` with `data-invalid` on `Field` and `aria-invalid` on the control — React Hook Form (`Controller` + Zod `zodResolver`), TanStack Form (`form.Field` render prop + Zod), Formisch (`Form` + `Field`, Valibot schema), Next.js (Server Action + `useActionState`, server-side Zod).

`@shadcn/react` = unstyled headless primitives (`@shadcn/react/questionnaire`, `@shadcn/react/message-scroller`); `@shadcn/helpers` (`/ai-sdk`, `/tanstack-ai`) = scripted `useChat` conversations for demos/tests, not UI. Typography for rendered markdown: shadcn/typeset (one `typeset.css`, `className="typeset"`).

---

## Composition Patterns

### Radix: `asChild`

```tsx
<Dialog.Trigger asChild>
  <Button variant="outline">Open</Button>
</Dialog.Trigger>
```

### Base UI: `render`

```tsx
<Dialog.Trigger render={<Button variant="outline" />}>
  Open
</Dialog.Trigger>
```

### React Aria: trigger wrapper (no `asChild`, no `render`)

```tsx
<DialogTrigger>
  <Button variant="outline">Open</Button>
  <Dialog>
    <DialogHeader>
      <DialogTitle>Title</DialogTitle>
    </DialogHeader>
  </Dialog>
</DialogTrigger>
```

---

## Reference Guide

### Concepts

| Topic | Reference | When to Consult |
|-------|-----------|-----------------|
| **Radix APIs** | [radix-components.md](references/radix-components.md) | Building with Radix primitives |
| **Base UI APIs** | [baseui-components.md](references/baseui-components.md) | Building with Base UI primitives |
| **React Aria APIs** | Tables above + [dialog-example.md](references/templates/dialog-example.md) | Building with React Aria primitives |

### Templates

| Template | When to Use |
|----------|-------------|
| [dialog-example.md](references/templates/dialog-example.md) | Creating Dialog components |

---

## Best Practices

### DO
- Detect primitive FIRST (use shadcn-detection)
- Consult MCP for component source before editing
- Follow existing naming conventions in project
- Use correct composition pattern for detected primitive

### DON'T
- Mix asChild, render and React Aria trigger wrappers in same component
- Assume Radix (or the new Base UI default) without detection
- Manually write component internals (use MCP)
- Skip registry check before adding new components

Attribution

fusenginefusengine
View sourceSee grades on GitHubMore from fusengine →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Terse caveman voice: answer first, fluff gone, every technical fact kept. Use for /caveman, "caveman mode", "talk like caveman", "be brief", "less tokens". Stays on until "stop caveman" or "normal mode".

1100021 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

698461 votes

Writing Skills

Create and manage Claude Code skills in HASH repository following Anthropic best practices. Use when creating new skills, modifying skill-rules.json, understanding trigger patterns, working with hooks, debugging skill activation, or implementing progressive disclosure. Covers skill structure, YAML frontmatter, trigger types (keywords, intent patterns), UserPromptSubmit hook, and the 500-line rule. Includes validation and debugging with SKILL_DEBUG. Examples include rust-error-stack, cargo-dep...

3931 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3421 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Amp, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Grok Build, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

741 votes
View all in ai-agents →