# shadcn-components > Manage Shadcn UI components: Add, Update, and Create custom components following best practices. - Author: Thamara Liyanage - Repository: wiztral/agent-skills - Version: 20260126112704 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-06 - Source: https://github.com/wiztral/agent-skills - Web: https://mule.run/skillshub/@@wiztral/agent-skills~shadcn-components:20260126112704 --- --- name: shadcn-components description: Manage Shadcn UI components: Add, Update, and Create custom components following best practices. --- # Shadcn Components Use this skill to add new components from the library or create custom components that align with Shadcn's architecture. ## Documentation - [Shadcn CLI](https://ui.shadcn.com/docs/cli) ## Workflow ### 1. Prerequisites - **Verify Initialization**: Check if `components.json` exists in the project root. - **If Missing**: Stop and run the `shadcn-setup` skill first. You cannot add components to an uninitialized project. ### 2. Add or Update Components To install a component from the registry: ```bash pnpm dlx shadcn@latest add [component-name] ``` - **Overwrite**: If the component exists and you are updating it, the CLI may ask to overwrite. Use `--overwrite` flag if you are certain. - **Multiple**: You can add multiple components at once: `pnpm dlx shadcn@latest add button card input`. ### 2. Create Custom Components (The "Shadcn Way") When creating a *new* component that isn't in the registry, follow these patterns: #### A. Structure Start with a file in `components/ui/` (or configured path). #### B. Imports **MUST** import the `cn` utility for class merging. ```tsx import * as React from "react" import { cva, type VariantProps } from "class-variance-authority" import { cn } from "@/lib/utils" ``` #### C. Variant Definitions with `cva` Define visual variants using `class-variance-authority`. ```tsx const badgeVariants = cva( "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", { variants: { variant: { default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", outline: "text-foreground", }, }, defaultVariants: { variant: "default", }, } ) ``` #### D. Component Definition - Export the interface extending HTML attributes. - Include `className` and `variant` props. - Use `cn()` to merge `className` prop with variants. - Set `displayName` for debugging if needed. ```tsx export interface BadgeProps extends React.HTMLAttributes, VariantProps {} function Badge({ className, variant, ...props }: BadgeProps) { return (
) } export { Badge, badgeVariants } ``` ### 3. Anti-Patterns ❌ - **Strings without `cn()`**: Never manually concat strings like `` `bg-red-500 ${className}` ``. Always use `cn()`. - **Ignoring Props**: Always spread `...props` to the underlying element to ensure accessibility attributes and event listeners pass through. ## References - [Form Patterns (Zod + HookForm)](references/form-patterns.md) - [Data Tables (TanStack)](references/data-table.md)