# Send Shadcn UI to your agent
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
## Fast path
- Download the package from Yavira.
- Extract it into a folder your agent can access.
- Paste one of the prompts below and point your agent at the extracted folder.
## Suggested prompts
### New install

```text
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete.
```
### Upgrade existing

```text
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run.
```
## Machine-readable fields
```json
{
  "schemaVersion": "1.0",
  "item": {
    "slug": "shadcn",
    "name": "Shadcn UI",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/wpank/shadcn",
    "canonicalUrl": "https://clawhub.ai/wpank/shadcn",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadUrl": "/downloads/shadcn",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=shadcn",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "packageFormat": "ZIP package",
    "primaryDoc": "SKILL.md",
    "includedAssets": [
      "README.md",
      "SKILL.md",
      "references/learn.md",
      "references/extended-components.md"
    ],
    "downloadMode": "redirect",
    "sourceHealth": {
      "source": "tencent",
      "slug": "shadcn",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-08T18:06:00.778Z",
      "expiresAt": "2026-05-15T18:06:00.778Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=shadcn",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=shadcn",
        "contentDisposition": "attachment; filename=\"shadcn-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null,
        "slug": "shadcn"
      },
      "scope": "item",
      "summary": "Item download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this item.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/shadcn"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    }
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/shadcn",
    "downloadUrl": "https://openagent3.xyz/downloads/shadcn",
    "agentUrl": "https://openagent3.xyz/skills/shadcn/agent",
    "manifestUrl": "https://openagent3.xyz/skills/shadcn/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/shadcn/agent.md"
  }
}
```
## Documentation

### shadcn/ui Component Patterns

Expert guide for building accessible, customizable UI components with shadcn/ui.

### OpenClaw / Moltbot / Clawbot

npx clawhub@latest install shadcn-ui

### WHEN

Setting up a new project with shadcn/ui
Installing or configuring individual components
Building forms with React Hook Form and Zod validation
Creating accessible UI components (buttons, dialogs, dropdowns, sheets)
Customizing component styling with Tailwind CSS
Implementing design systems with shadcn/ui
Building Next.js applications with TypeScript

### What is shadcn/ui?

A collection of reusable components you copy into your project — not an npm package. You own the code. Built on Radix UI (accessibility) and Tailwind CSS (styling).

### Quick Start

# New Next.js project
npx create-next-app@latest my-app --typescript --tailwind --eslint --app
cd my-app
npx shadcn@latest init

# Install components
npx shadcn@latest add button input form card dialog select toast
npx shadcn@latest add --all  # or install everything

### The cn Utility

Merges Tailwind classes with conflict resolution — used in every component:

import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

### Class Variance Authority (CVA)

Manages component variants — the pattern behind every shadcn/ui component:

import { cva, type VariantProps } from "class-variance-authority"

const buttonVariants = cva(
  "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground hover:bg-primary/90",
        destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
        outline: "border border-input bg-background hover:bg-accent",
        secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/90",
        ghost: "hover:bg-accent hover:text-accent-foreground",
        link: "text-primary underline-offset-4 hover:underline",
      },
      size: {
        default: "h-10 px-4 py-2",
        sm: "h-9 rounded-md px-3",
        lg: "h-11 rounded-md px-8",
        icon: "h-10 w-10",
      },
    },
    defaultVariants: { variant: "default", size: "default" },
  }
)

### Button

import { Button } from "@/components/ui/button"
import { Loader2 } from "lucide-react"

// Variants: default | destructive | outline | secondary | ghost | link
// Sizes: default | sm | lg | icon
<Button variant="outline" size="sm">Click me</Button>

// Loading state
<Button disabled>
  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
  Please wait
</Button>

// As link (uses Radix Slot)
<Button asChild>
  <a href="/dashboard">Go to Dashboard</a>
</Button>

### Forms with Validation

The standard pattern: Zod schema + React Hook Form + shadcn Form components.

npx shadcn@latest add form input select checkbox textarea

"use client"

import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import * as z from "zod"
import { Button } from "@/components/ui/button"
import {
  Form, FormControl, FormDescription,
  FormField, FormItem, FormLabel, FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"

const formSchema = z.object({
  username: z.string().min(2, "Username must be at least 2 characters."),
  email: z.string().email("Please enter a valid email."),
  role: z.enum(["admin", "user", "guest"]),
})

export function ProfileForm() {
  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: { username: "", email: "", role: "user" },
  })

  function onSubmit(values: z.infer<typeof formSchema>) {
    console.log(values)
  }

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
        <FormField control={form.control} name="username" render={({ field }) => (
          <FormItem>
            <FormLabel>Username</FormLabel>
            <FormControl><Input placeholder="shadcn" {...field} /></FormControl>
            <FormDescription>Your public display name.</FormDescription>
            <FormMessage />
          </FormItem>
        )} />

        <FormField control={form.control} name="email" render={({ field }) => (
          <FormItem>
            <FormLabel>Email</FormLabel>
            <FormControl><Input type="email" {...field} /></FormControl>
            <FormMessage />
          </FormItem>
        )} />

        <FormField control={form.control} name="role" render={({ field }) => (
          <FormItem>
            <FormLabel>Role</FormLabel>
            <Select onValueChange={field.onChange} defaultValue={field.value}>
              <FormControl>
                <SelectTrigger><SelectValue placeholder="Select a role" /></SelectTrigger>
              </FormControl>
              <SelectContent>
                <SelectItem value="admin">Admin</SelectItem>
                <SelectItem value="user">User</SelectItem>
                <SelectItem value="guest">Guest</SelectItem>
              </SelectContent>
            </Select>
            <FormMessage />
          </FormItem>
        )} />

        <Button type="submit">Submit</Button>
      </form>
    </Form>
  )
}

### Dialog & Sheet

import {
  Dialog, DialogContent, DialogDescription,
  DialogFooter, DialogHeader, DialogTitle, DialogTrigger,
} from "@/components/ui/dialog"
import {
  Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger,
} from "@/components/ui/sheet"

// Modal dialog
<Dialog>
  <DialogTrigger asChild><Button variant="outline">Edit profile</Button></DialogTrigger>
  <DialogContent className="sm:max-w-[425px]">
    <DialogHeader>
      <DialogTitle>Edit profile</DialogTitle>
      <DialogDescription>Make changes here. Click save when done.</DialogDescription>
    </DialogHeader>
    <div className="grid gap-4 py-4">{/* form fields */}</div>
    <DialogFooter><Button type="submit">Save changes</Button></DialogFooter>
  </DialogContent>
</Dialog>

// Slide-over panel (side: "left" | "right" | "top" | "bottom")
<Sheet>
  <SheetTrigger asChild><Button variant="outline">Open</Button></SheetTrigger>
  <SheetContent side="right">
    <SheetHeader><SheetTitle>Settings</SheetTitle></SheetHeader>
    {/* content */}
  </SheetContent>
</Sheet>

### Card

import {
  Card, CardContent, CardDescription,
  CardFooter, CardHeader, CardTitle,
} from "@/components/ui/card"

<Card className="w-[350px]">
  <CardHeader>
    <CardTitle>Create project</CardTitle>
    <CardDescription>Deploy your new project in one-click.</CardDescription>
  </CardHeader>
  <CardContent>
    <div className="grid w-full items-center gap-4">
      <div className="flex flex-col space-y-1.5">
        <Label htmlFor="name">Name</Label>
        <Input id="name" placeholder="Project name" />
      </div>
    </div>
  </CardContent>
  <CardFooter className="flex justify-between">
    <Button variant="outline">Cancel</Button>
    <Button>Deploy</Button>
  </CardFooter>
</Card>

### Toast Notifications

// 1. Add Toaster to root layout
import { Toaster } from "@/components/ui/toaster"

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}<Toaster /></body>
    </html>
  )
}

// 2. Use toast in components
import { useToast } from "@/components/ui/use-toast"
import { ToastAction } from "@/components/ui/toast"

const { toast } = useToast()

toast({ title: "Success", description: "Changes saved." })

toast({
  variant: "destructive",
  title: "Error",
  description: "Something went wrong.",
  action: <ToastAction altText="Try again">Try again</ToastAction>,
})

### Table

import {
  Table, TableBody, TableCaption, TableCell,
  TableHead, TableHeader, TableRow,
} from "@/components/ui/table"

const invoices = [
  { invoice: "INV001", status: "Paid", method: "Credit Card", amount: "$250.00" },
  { invoice: "INV002", status: "Pending", method: "PayPal", amount: "$150.00" },
]

<Table>
  <TableCaption>A list of your recent invoices.</TableCaption>
  <TableHeader>
    <TableRow>
      <TableHead>Invoice</TableHead>
      <TableHead>Status</TableHead>
      <TableHead>Method</TableHead>
      <TableHead className="text-right">Amount</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    {invoices.map((invoice) => (
      <TableRow key={invoice.invoice}>
        <TableCell className="font-medium">{invoice.invoice}</TableCell>
        <TableCell>{invoice.status}</TableCell>
        <TableCell>{invoice.method}</TableCell>
        <TableCell className="text-right">{invoice.amount}</TableCell>
      </TableRow>
    ))}
  </TableBody>
</Table>

### Theming

shadcn/ui uses CSS variables in HSL format. Configure in globals.css:

@layer base {
  :root {
    --background: 0 0% 100%;
    --foreground: 222.2 84% 4.9%;
    --primary: 222.2 47.4% 11.2%;
    --primary-foreground: 210 40% 98%;
    --secondary: 210 40% 96.1%;
    --muted: 210 40% 96.1%;
    --muted-foreground: 215.4 16.3% 46.9%;
    --destructive: 0 84.2% 60.2%;
    --border: 214.3 31.8% 91.4%;
    --ring: 222.2 84% 4.9%;
    --radius: 0.5rem;
  }

  .dark {
    --background: 222.2 84% 4.9%;
    --foreground: 210 40% 98%;
    --primary: 210 40% 98%;
    --primary-foreground: 222.2 47.4% 11.2%;
    /* ... mirror all variables for dark mode */
  }
}

Colors reference as hsl(var(--primary)) in Tailwind config. Change the CSS variables to retheme the entire app.

### Customizing Components

Since you own the code, modify components directly:

// Add a custom variant to button.tsx
const buttonVariants = cva("...", {
  variants: {
    variant: {
      // ... existing variants
      gradient: "bg-gradient-to-r from-purple-500 to-pink-500 text-white",
    },
    size: {
      // ... existing sizes
      xl: "h-14 rounded-md px-10 text-lg",
    },
  },
})

### Component Reference

ComponentInstallKey PropsButtonadd buttonvariant, size, asChildInputadd inputStandard HTML input propsFormadd formReact Hook Form + Zod integrationCardadd cardHeader, Content, Footer compositionDialogadd dialogModal with trigger patternSheetadd sheetSlide-over panel, side propSelectadd selectAccessible dropdownToastadd toastvariant: "default" | "destructive"Tableadd tableHeader, Body, Row, Cell compositionTabsadd tabsdefaultValue, trigger/content pairsAccordionadd accordiontype: "single" | "multiple"Commandadd commandCommand palette / searchDropdown Menuadd dropdown-menuContext menus, action menusMenubaradd menubarApplication menus with shortcuts

### App Router Setup

For Next.js 13+ with App Router, ensure interactive components use "use client":

// src/components/ui/button.tsx
"use client"

import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
// ... rest of component

### Layout Integration

Add the Toaster to your root layout:

// app/layout.tsx
import { Toaster } from "@/components/ui/toaster"
import "./globals.css"

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body className="min-h-screen bg-background font-sans antialiased">
        {children}
        <Toaster />
      </body>
    </html>
  )
}

### Server Components

Most shadcn/ui components need "use client". For Server Components, wrap them in a client component or use them in client component children.

### CLI Reference

npx shadcn@latest init              # Initialize project
npx shadcn@latest add [component]   # Add specific component
npx shadcn@latest add --all         # Add all components
npx shadcn@latest diff              # Show upstream changes

### Best Practices

PracticeDetailsUse TypeScriptAll components ship with full type definitionsZod for validationPair with React Hook Form for type-safe formsasChild patternUse Radix Slot to render as different elementsServer ComponentsMost shadcn/ui components need "use client"Consistent structureFollow the existing component patterns when customizingAccessibilityRadix primitives handle ARIA; don't override without reasonCSS variablesTheme via variables, not by editing component classesTree-shakingOnly install components you need — they're independent

### NEVER Do

NeverWhyInsteadInstall shadcn as npm packageIt's not a package — it's source code you ownUse CLI: npx shadcn@latest addOverride ARIA attributesRadix handles accessibility correctlyTrust the primitivesUse inline styles for themingDefeats the design systemModify CSS variablesCopy components from docs manuallyMay miss dependenciesUse CLI for proper installationMix component stylesCreates inconsistencyFollow CVA variant pattern

### References

Learning Guide — progression from basics to advanced patterns
Extended Components — Terminal, Dock, Charts, animations, custom hooks
Official Docs | Radix UI | React Hook Form | Zod
## Trust
- Source: tencent
- Verification: Indexed source record
- Publisher: wpank
- Version: 1.0.0
## Source health
- Status: healthy
- Item download looks usable.
- Yavira can redirect you to the upstream package for this item.
- Health scope: item
- Reason: direct_download_ok
- Checked at: 2026-05-08T18:06:00.778Z
- Expires at: 2026-05-15T18:06:00.778Z
- Recommended action: Download for OpenClaw
## Links
- [Detail page](https://openagent3.xyz/skills/shadcn)
- [Send to Agent page](https://openagent3.xyz/skills/shadcn/agent)
- [JSON manifest](https://openagent3.xyz/skills/shadcn/agent.json)
- [Markdown brief](https://openagent3.xyz/skills/shadcn/agent.md)
- [Download page](https://openagent3.xyz/downloads/shadcn)