/shadcn-vue
Manages shadcn-vue components and projects — adding, searching, fixing, debugging, styling, and composing UI. Provides project context, component docs, and usage examples. Applies when working with shadcn-vue, component registries, presets, --preset codes, or any project with a
Claude Code
$ npx -y skills add unovue/shadcn-vue --skill shadcn-vue --agent claude-code
Codex
$ npx skills add unovue/shadcn-vue --skill shadcn-vue -a codex -y
Cursor
$ npx skills add unovue/shadcn-vue --skill shadcn-vue -a cursor -y
Gemini CLI
$ npx skills add unovue/shadcn-vue --skill shadcn-vue -a gemini-cli -y
GitHub Copilot
$ npx skills add unovue/shadcn-vue --skill shadcn-vue -a github-copilot -y
OpenCode
$ npx skills add unovue/shadcn-vue --skill shadcn-vue -a opencode -y
Windsurf
$ npx skills add unovue/shadcn-vue --skill shadcn-vue -a windsurf -y
SKILL.md
shadcn-vue.SKILL.mdname: shadcn-vue
description: Manages shadcn-vue components and projects — adding, searching, fixing, debugging, styling, and composing UI. Provides project context, component docs, and usage examples. Applies when working with shadcn-vue, component registries, presets, --preset codes, or any project with a components.json file. Also triggers for "shadcn-vue init", "create an app with --preset", or "switch to --preset".
user-invocable: false
allowed-tools: Bash(npx shadcn-vue@latest *), Bash(pnpm dlx shadcn-vue@latest *), Bash(bunx --bun shadcn-vue@latest *)
shadcn-vue
A framework for building ui, components and design systems. Components are added as source code to the user's project via the CLI.
> **IMPORTANT:** Run all CLI commands using the project's package runner: `npx shadcn-vue@latest`, `pnpm dlx shadcn-vue@latest`, or `bunx --bun shadcn-vue@latest` — based on the project's `packageManager`. Examples below use `npx shadcn-vue@latest` but substitute the correct runner for the project.
Current Project Context
!`npx shadcn-vue@latest info --json`
The JSON above has two keys: `project` (detected framework, Tailwind setup, package manager) and `config` (the resolved `components.json`). It does not list installed components — list the `config.resolvedPaths.ui` directory for that. Use `npx shadcn-vue@latest docs <component>` to get the documentation URL for any component.
Principles
1. **Use existing components first.** Use `npx shadcn-vue@latest search` to check registries before writing custom UI. Check community registries too. 2. **Compose, don't reinvent.** Settings page = Tabs + Card + form controls. Dashboard = Sidebar + Card + Chart + Table. 3. **Use built-in variants before custom styles.** `variant="outline"`, `size="sm"`, etc. 4. **Use semantic colors.** `bg-primary`, `text-muted-foreground` — never raw values like `bg-blue-500`.
Critical Rules
These rules are **always enforced**. Each links to a file with Incorrect/Correct code pairs.
Styling & Tailwind → [styling.md](./rules/styling.md)
- **`class` for layout, not styling.** Never override component colors or typography.
- **No `space-x-*` or `space-y-*`.** Use `flex` with `gap-*`. For vertical stacks, `flex flex-col gap-*`.
- **Use `size-*` when width and height are equal.** `size-10` not `w-10 h-10`.
- **Use `truncate` shorthand.** Not `overflow-hidden text-ellipsis whitespace-nowrap`.
- **No manual `dark:` color overrides.** Use semantic tokens (`bg-background`, `text-muted-foreground`).
- **Use `cn()` for conditional classes.** Don't write manual template literal ternaries.
- **No manual `z-index` on overlay components.** Dialog, Sheet, Popover, etc. handle their own stacking.
Forms & Inputs → [forms.md](./rules/forms.md)
- **Forms use `FieldGroup` + `Field`.** Never use raw `div` with `space-y-*` or `grid gap-*` for form layout.
- **`InputGroup` uses `InputGroupInput`/`InputGroupTextarea`.** Never raw `Input`/`Textarea` inside `InputGroup`.
- **Buttons inside inputs use `InputGroup` + `InputGroupAddon`.**
- **Option sets (2–7 choices) use `ToggleGroup`.** Don't loop `Button` with manual active state.
- **`FieldSet` + `FieldLegend` for grouping related checkboxes/radios.** Don't use a `div` with a heading.
- **Field validation uses `data-invalid` + `aria-invalid` + `FieldError`.** `data-invalid` on `Field`, `aria-invalid` on the control, message in `FieldError` (not `FieldDescription`). For disabled: `data-disabled` on `Field`, `disabled` on the control.
- **Form state comes from a form library** (vee-validate, TanStack Form, Formisch) wired into `Field`. Don't use the legacy `Form`/`FormField` components.
Component Structure → [composition.md](./rules/composition.md)
- **Items always inside their Group.** `SelectItem` → `SelectGroup`. `DropdownMenuItem` → `DropdownMenuGroup`. `CommandItem` → `CommandGroup`.
- **Dialog, Sheet, and Drawer always need a Title.** `DialogTitle`, `SheetTitle`, `DrawerTitle` required for accessibility. Use `class="sr-only"` if visually hidden.
- **Use full Card composition.** `CardHeader`/`CardTitle`/`CardDescription`/`CardContent`/`CardFooter`. Don't dump everything in `CardContent`.
- **Button has no `isPending`/`isLoading`.** Compose with `Spinner` + `data-icon` + `disabled`.
- **`TabsTrigger` must be inside `TabsList`.** Never render triggers directly in `Tabs`.
- **`Avatar` always needs `AvatarFallback`.** For when the image fails to load.
Use Components, Not Custom Markup → [composition.md](./rules/composition.md)
- **Use existing components before custom markup.** Check if a component exists before writing a styled `div`.
- **Callouts use `Alert`.** Don't build custom styled divs.
- **Empty states use `Empty`.** Don't build custom empty state markup.
- **Toast via `vue-sonner`.** Use `toast()` from `vue-sonner`. Mount `<Toaster />` (from the `sonner` component) once in the root layout and import `vue-sonner/style.css`.
- **Use `Separator`** instead of `<hr>` or `<div class="border-t">`.
- **Use `Skeleton`** for loading placeholders. No custom `animate-pulse` divs.
- **Use `Badge`** instead of custom styled spans.
Icons → [icons.md](./rules/icons.md)
- **Icons in `Button` use `data-icon`.** `data-icon="inline-start"` or `data-icon="inline-end"` on the icon. (Styled only by the `reka-*` styles; the classic `new-york` and `new-york-v4` styles ignore it, space icons with `gap-2`, and size them automatically.)
- **No sizing classes on icons inside components.** Components handle icon sizing via CSS. No `size-4` or `w-4 h-4`.
- **Pass icons as objects, not string keys.** `:icon="CheckIcon"`, not a string lookup.
CLI
- **Apply preset codes directly with the CLI.** Use `npx shadcn-vue@latest apply <code>` for existing projects, or `npx shadcn-vue@latest init --preset <code>` when initializing.
Key Patterns
These are the most common patterns that differentiate correct shadcn-vue code. For edge cases, see the linke
Read more
name: shadcn-vue description: Manages shadcn-vue components and projects — adding, searching, fixing, debugging, styling, and composing UI. Provides project context, component docs, and usage examples. Applies when working with shadcn-vue, component registries, presets, --preset codes, or any project with a components.json file. Also triggers for "shadcn-vue init", "create an app with --preset", or "switch to --preset". user-invocable: false allowed-tools: Bash(npx shadcn-vue@latest *), Bash(pnpm dlx shadcn-vue@latest *), Bash(bunx --bun shadcn-vue@latest *)
shadcn-vue
A framework for building ui, components and design systems. Components are added as source code to the user's project via the CLI.
> **IMPORTANT:** Run all CLI commands using the project's package runner: `npx shadcn-vue@latest`, `pnpm dlx shadcn-vue@latest`, or `bunx --bun shadcn-vue@latest` — based on the project's `packageManager`. Examples below use `npx shadcn-vue@latest` but substitute the correct runner for the project.
Current Project Context
!`npx shadcn-vue@latest info --json`
The JSON above has two keys: `project` (detected framework, Tailwind setup, package manager) and `config` (the resolved `components.json`). It does not list installed components — list the `config.resolvedPaths.ui` directory for that. Use `npx shadcn-vue@latest docs <component>` to get the documentation URL for any component.
Principles
1. **Use existing components first.** Use `npx shadcn-vue@latest search` to check registries before writing custom UI. Check community registries too. 2. **Compose, don't reinvent.** Settings page = Tabs + Card + form controls. Dashboard = Sidebar + Card + Chart + Table. 3. **Use built-in variants before custom styles.** `variant="outline"`, `size="sm"`, etc. 4. **Use semantic colors.** `bg-primary`, `text-muted-foreground` — never raw values like `bg-blue-500`.
Critical Rules
These rules are **always enforced**. Each links to a file with Incorrect/Correct code pairs.
Styling & Tailwind → [styling.md](./rules/styling.md)
- **`class` for layout, not styling.** Never override component colors or typography.
- **No `space-x-*` or `space-y-*`.** Use `flex` with `gap-*`. For vertical stacks, `flex flex-col gap-*`.
- **Use `size-*` when width and height are equal.** `size-10` not `w-10 h-10`.
- **Use `truncate` shorthand.** Not `overflow-hidden text-ellipsis whitespace-nowrap`.
- **No manual `dark:` color overrides.** Use semantic tokens (`bg-background`, `text-muted-foreground`).
- **Use `cn()` for conditional classes.** Don't write manual template literal ternaries.
- **No manual `z-index` on overlay components.** Dialog, Sheet, Popover, etc. handle their own stacking.
Forms & Inputs → [forms.md](./rules/forms.md)
- **Forms use `FieldGroup` + `Field`.** Never use raw `div` with `space-y-*` or `grid gap-*` for form layout.
- **`InputGroup` uses `InputGroupInput`/`InputGroupTextarea`.** Never raw `Input`/`Textarea` inside `InputGroup`.
- **Buttons inside inputs use `InputGroup` + `InputGroupAddon`.**
- **Option sets (2–7 choices) use `ToggleGroup`.** Don't loop `Button` with manual active state.
- **`FieldSet` + `FieldLegend` for grouping related checkboxes/radios.** Don't use a `div` with a heading.
- **Field validation uses `data-invalid` + `aria-invalid` + `FieldError`.** `data-invalid` on `Field`, `aria-invalid` on the control, message in `FieldError` (not `FieldDescription`). For disabled: `data-disabled` on `Field`, `disabled` on the control.
- **Form state comes from a form library** (vee-validate, TanStack Form, Formisch) wired into `Field`. Don't use the legacy `Form`/`FormField` components.
Component Structure → [composition.md](./rules/composition.md)
- **Items always inside their Group.** `SelectItem` → `SelectGroup`. `DropdownMenuItem` → `DropdownMenuGroup`. `CommandItem` → `CommandGroup`.
- **Dialog, Sheet, and Drawer always need a Title.** `DialogTitle`, `SheetTitle`, `DrawerTitle` required for accessibility. Use `class="sr-only"` if visually hidden.
- **Use full Card composition.** `CardHeader`/`CardTitle`/`CardDescription`/`CardContent`/`CardFooter`. Don't dump everything in `CardContent`.
- **Button has no `isPending`/`isLoading`.** Compose with `Spinner` + `data-icon` + `disabled`.
- **`TabsTrigger` must be inside `TabsList`.** Never render triggers directly in `Tabs`.
- **`Avatar` always needs `AvatarFallback`.** For when the image fails to load.
Use Components, Not Custom Markup → [composition.md](./rules/composition.md)
- **Use existing components before custom markup.** Check if a component exists before writing a styled `div`.
- **Callouts use `Alert`.** Don't build custom styled divs.
- **Empty states use `Empty`.** Don't build custom empty state markup.
- **Toast via `vue-sonner`.** Use `toast()` from `vue-sonner`. Mount `<Toaster />` (from the `sonner` component) once in the root layout and import `vue-sonner/style.css`.
- **Use `Separator`** instead of `<hr>` or `<div class="border-t">`.
- **Use `Skeleton`** for loading placeholders. No custom `animate-pulse` divs.
- **Use `Badge`** instead of custom styled spans.
Icons → [icons.md](./rules/icons.md)
- **Icons in `Button` use `data-icon`.** `data-icon="inline-start"` or `data-icon="inline-end"` on the icon. (Styled only by the `reka-*` styles; the classic `new-york` and `new-york-v4` styles ignore it, space icons with `gap-2`, and size them automatically.)
- **No sizing classes on icons inside components.** Components handle icon sizing via CSS. No `size-4` or `w-4 h-4`.
- **Pass icons as objects, not string keys.** `:icon="CheckIcon"`, not a string lookup.
CLI
- **Apply preset codes directly with the CLI.** Use `npx shadcn-vue@latest apply <code>` for existing projects, or `npx shadcn-vue@latest init --preset <code>` when initializing.
Key Patterns
These are the most common patterns that differentiate correct shadcn-vue code. For edge cases, see the linke
A set of beautifully designed components that you can customize, extend, and build on. Start here then make it your own. Open Source. Open Code. Use this to build your own component library.
More skills from other plugins.
migrate-radix-to-base
Migrates React projects and components from Radix UI to Base UI. Use when asked to migrate from radix, move to base-ui, convert…
taste-skill
tasteskill v2, the anti-slop frontend skill. Art direction for websites, distilled from a study of 247 curated gallery sites (One…
Questions about shadcn-vue.
- Which coding agents can use shadcn-vue?
- shadcn-vue installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

