shadcn-best-practices

Best practices for working with shadcn/ui components, imports, theming, and forms. Use when building UI with shadcn, adding components, configuring theming, or creating forms.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "shadcn-best-practices" with this command: npx skills add moderndegree/agent-skills/moderndegree-agent-skills-shadcn-best-practices

shadcn/ui Best Practices

This skill covers best practices for working with shadcn/ui — component imports, className utilities, form building, theming, and data tables.

Use-When

This skill activates when:

  • Agent works with shadcn/ui components
  • Agent adds or imports shadcn components
  • Agent builds forms with validation
  • Agent configures theming or dark mode
  • Agent creates data tables

Core Rules

  • ALWAYS import shadcn components from @/components/ui/{component-name}
  • ALWAYS use the cn() utility for className merging
  • ALWAYS use Zod + React Hook Form for form validation
  • ALWAYS use CSS variables for theming (not hardcoded colors)
  • ALWAYS use TanStack Table for data tables
  • ALWAYS check components.json to identify the primitive library (Radix vs Base UI)
  • ALWAYS use migration commands when upgrading between styles (migrate radix, migrate rtl)

Common Agent Mistakes

  • Using relative paths instead of alias paths
  • Forgetting to import cn() utility
  • Hardcoding colors instead of using CSS variables
  • Building table logic manually instead of using TanStack Table
  • Assuming all shadcn projects use Radix UI (Base UI is now available)
  • Using Radix-specific imports in Base UI projects (or vice versa)

Examples

✅ Correct

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { cn } from "@/lib/utils"

function MyComponent({ className }) {
  return (
    <Button className={cn("base-class", className)}>
      <Input placeholder="Enter email" />
    </Button>
  )
}

❌ Wrong

// Using relative paths
import { Button } from "../../components/ui/button"

// Hardcoding colors
<Button className="bg-blue-500 text-white" />

// Building table manually
data.map(item => <tr><td>{item.name}</td></tr>)

// Assuming Radix - wrong for Base UI projects
import * as DialogPrimitive from "@radix-ui/react-dialog"

Identifying Primitive Library

// Check components.json to determine which library the project uses
// Look for "style" field:
// - "base-*" styles use @base-ui/react
// - Other styles use @radix-ui/react-* or radix-ui

// Example: reading the config
// import fs from "fs"
// const config = JSON.parse(fs.readFileSync("components.json", "utf-8"))
// config.style === "base-vega" // true = Base UI, false = Radix

// The API is identical regardless of library
import { Dialog, DialogContent } from "@/components/ui/dialog"
// Works the same for both Radix and Base UI projects

References

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

design-systems

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

dialogs-modals

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

a11y-best-practices

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

form-design

No summary provided by upstream source.

Repository SourceNeeds Review