skillZs
★ LIVE SKILL TAGS ★
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
※ REAL INSTALL DATA ※
← back to all skills
reason-machines/design-skills109 installs

better-design-shadcn-themes

Install and use themed shadcn/ui components from 31+ design systems (Linear, Stripe, Apple, Notion, etc.) with one command

How do I install this agent skill?

npx skills add https://github.com/reason-machines/design-skills --skill better-design-shadcn-themes
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubwarn

    The skill provides instructions to download and integrate external UI components from a third-party registry (better-design.com) using the shadcn CLI. This process involves fetching remote code and dependencies into the local project environment.

  • Socketwarn

    1 alert: gptAnomaly

  • Snykwarn

    Risk: MEDIUM · 1 issue

What does this agent skill do?

better-design-shadcn-themes

Skill by ara.so — Design Skills collection.

Overview

Better Design provides 31+ production-ready design systems for shadcn/ui. Each design system includes ~89 fully themed components (buttons, cards, dialogs, forms, etc.) that you can install directly into your shadcn/ui project with a single CLI command. All design systems are MIT licensed and include popular styles like Linear, Stripe, Airbnb, Apple, Notion, Vercel, Supabase, and Figma.

Browse all design systems at: https://better-design.com/design-systems

Installation

Better Design components install directly into existing shadcn/ui projects using the shadcn CLI. There's no separate package to install — you pull individual components on-demand.

Prerequisites

Your project must already have shadcn/ui initialized:

npx shadcn@latest init

Core Commands

Install a Single Component

npx shadcn@latest add https://www.better-design.com/registry/<design-system>/<component>.json

Examples:

# Install Linear-styled button
npx shadcn@latest add https://www.better-design.com/registry/linear/button.json

# Install Stripe-styled card
npx shadcn@latest add https://www.better-design.com/registry/stripe/card.json

# Install Apple-styled dialog
npx shadcn@latest add https://www.better-design.com/registry/apple/dialog.json

# Install Notion-styled input
npx shadcn@latest add https://www.better-design.com/registry/notion/input.json

The CLI automatically:

  • Downloads the component TypeScript file
  • Installs required dependencies
  • Updates CSS variables in globals.css
  • Handles component dependencies

Install Multiple Components

# Install several components from the same design system
npx shadcn@latest add \
  https://www.better-design.com/registry/linear/button.json \
  https://www.better-design.com/registry/linear/input.json \
  https://www.better-design.com/registry/linear/card.json

Available Design Systems

Design System SlugStyleBest For
linearClean, modern, darkProject management, SaaS
stripeProfessional, minimalFintech, payments
applePolished, refinedConsumer apps
notionSoft, approachableNote-taking, docs
vercelSleek, high-contrastDeveloper tools
supabaseBold, green accentBackend tools, dashboards
figmaColorful, playfulDesign tools
airbnbWarm, friendlyMarketplace, social
beam-libGradient, modernCreative tools
corporate-fintechConservative, trustEnterprise, finance
glassmorphic-darkFrosted glass effectModern dark UIs
minimal-lightUltra-clean lightContent-first apps
midnight-glassDark with glassPremium apps
vibrant-darkHigh-saturation darkGaming, entertainment

Full list of 31 design systems: https://better-design.com/design-systems

Component Usage Patterns

Basic Component Import

After installing a component, import and use it like any shadcn component:

import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Input } from "@/components/ui/input"

export default function MyPage() {
  return (
    <Card>
      <CardHeader>
        <CardTitle>Linear-styled Card</CardTitle>
      </CardHeader>
      <CardContent>
        <Input placeholder="Enter text..." />
        <Button>Submit</Button>
      </CardContent>
    </Card>
  )
}

Mixing Design Systems

You can install components from different design systems in the same project:

// Linear button with Stripe card
import { Button } from "@/components/ui/button" // Linear
import { Card } from "@/components/ui/card" // Stripe

export default function MixedDesign() {
  return (
    <Card className="p-6">
      <h2>Checkout</h2>
      <Button>Pay with Linear button style</Button>
    </Card>
  )
}

Note: CSS variables may conflict when mixing design systems. For best results, stick to one design system per project or carefully test combinations.

Form Components Example

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Textarea } from "@/components/ui/textarea"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"

export default function ContactForm() {
  return (
    <form className="space-y-4">
      <div>
        <Label htmlFor="name">Name</Label>
        <Input id="name" placeholder="John Doe" />
      </div>
      
      <div>
        <Label htmlFor="email">Email</Label>
        <Input id="email" type="email" placeholder="john@example.com" />
      </div>
      
      <div>
        <Label htmlFor="topic">Topic</Label>
        <Select>
          <SelectTrigger id="topic">
            <SelectValue placeholder="Select a topic" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="support">Support</SelectItem>
            <SelectItem value="sales">Sales</SelectItem>
            <SelectItem value="feedback">Feedback</SelectItem>
          </SelectContent>
        </Select>
      </div>
      
      <div>
        <Label htmlFor="message">Message</Label>
        <Textarea id="message" placeholder="Your message..." />
      </div>
      
      <Button type="submit">Send Message</Button>
    </form>
  )
}

Dialog Component Example

import { Button } from "@/components/ui/button"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export default function EditProfileDialog() {
  return (
    <Dialog>
      <DialogTrigger asChild>
        <Button variant="outline">Edit Profile</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Edit profile</DialogTitle>
          <DialogDescription>
            Make changes to your profile here. Click save when you're done.
          </DialogDescription>
        </DialogHeader>
        <div className="grid gap-4 py-4">
          <div className="grid grid-cols-4 items-center gap-4">
            <Label htmlFor="username" className="text-right">
              Username
            </Label>
            <Input id="username" defaultValue="@johndoe" className="col-span-3" />
          </div>
        </div>
        <DialogFooter>
          <Button type="submit">Save changes</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

Data Table Example

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

const invoices = [
  { id: "INV001", status: "Paid", amount: "$250.00" },
  { id: "INV002", status: "Pending", amount: "$150.00" },
  { id: "INV003", status: "Paid", amount: "$350.00" },
]

export default function InvoiceTable() {
  return (
    <Table>
      <TableCaption>A list of your recent invoices.</TableCaption>
      <TableHeader>
        <TableRow>
          <TableHead>Invoice</TableHead>
          <TableHead>Status</TableHead>
          <TableHead>Amount</TableHead>
          <TableHead className="text-right">Actions</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {invoices.map((invoice) => (
          <TableRow key={invoice.id}>
            <TableCell className="font-medium">{invoice.id}</TableCell>
            <TableCell>
              <Badge variant={invoice.status === "Paid" ? "default" : "secondary"}>
                {invoice.status}
              </Badge>
            </TableCell>
            <TableCell>{invoice.amount}</TableCell>
            <TableCell className="text-right">
              <Button variant="ghost" size="sm">View</Button>
            </TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  )
}

Available Components

Each design system includes ~89 components:

Layout & Structure:

  • accordion, card, separator, tabs, table

Forms & Input:

  • button, input, textarea, checkbox, radio-group, select, slider, switch, form, label

Feedback & Overlays:

  • dialog, alert-dialog, drawer, sheet, popover, tooltip, toast, alert, badge, progress, skeleton

Navigation:

  • navigation-menu, menubar, dropdown-menu, context-menu, breadcrumb, pagination, command

Data Display:

  • avatar, calendar, chart, carousel, collapsible, data-table, hover-card, aspect-ratio

Typography:

  • typography

Configuration

CSS Variables

Each design system uses CSS variables defined in globals.css. When you install your first component from a design system, the CLI updates globals.css with theme tokens:

@layer base {
  :root {
    --background: 0 0% 100%;
    --foreground: 0 0% 3.9%;
    --card: 0 0% 100%;
    --card-foreground: 0 0% 3.9%;
    --primary: 0 0% 9%;
    --primary-foreground: 0 0% 98%;
    /* ... more variables */
  }

  .dark {
    --background: 0 0% 3.9%;
    --foreground: 0 0% 98%;
    /* ... dark mode overrides */
  }
}

These variables are automatically configured — you don't need to manually edit them.

Tailwind Configuration

Better Design components use your existing shadcn Tailwind config. Ensure your tailwind.config.ts has the shadcn setup:

import type { Config } from "tailwindcss"

const config: Config = {
  darkMode: ["class"],
  content: [
    "./pages/**/*.{ts,tsx}",
    "./components/**/*.{ts,tsx}",
    "./app/**/*.{ts,tsx}",
    "./src/**/*.{ts,tsx}",
  ],
  theme: {
    extend: {
      colors: {
        border: "hsl(var(--border))",
        input: "hsl(var(--input))",
        ring: "hsl(var(--ring))",
        background: "hsl(var(--background))",
        foreground: "hsl(var(--foreground))",
        primary: {
          DEFAULT: "hsl(var(--primary))",
          foreground: "hsl(var(--primary-foreground))",
        },
        // ... other color definitions
      },
      borderRadius: {
        lg: "var(--radius)",
        md: "calc(var(--radius) - 2px)",
        sm: "calc(var(--radius) - 4px)",
      },
    },
  },
  plugins: [require("tailwindcss-animate")],
}

export default config

Repository Structure

If forking or contributing to the Better Design repo:

registry/
  <design-system>/
    button.json        # Registry entry for shadcn CLI
    card.json
    input.json
    ...
  index.json           # Registry manifest

components/
  <design-system>/
    components/ui/     # Readable TypeScript source
      button.tsx
      card.tsx
      ...
    globals.css        # CSS variables for the theme
    lib/utils.ts       # cn() utility
  • registry/ — Source of truth for CLI installations (JSON format)
  • components/ — Human-readable .tsx files for browsing/copying

Both directories stay in sync. When forking, copy both the component and matching globals.css.

Common Patterns

Creating a Landing Page Hero

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

export default function Hero() {
  return (
    <section className="flex min-h-screen flex-col items-center justify-center px-4">
      <h1 className="text-5xl font-bold tracking-tight">
        Ship faster with Better Design
      </h1>
      <p className="mt-4 text-xl text-muted-foreground">
        31+ design systems for shadcn/ui. Install with one command.
      </p>
      <div className="mt-8 flex gap-4">
        <Button size="lg">Get Started</Button>
        <Button size="lg" variant="outline">View Designs</Button>
      </div>
      <div className="mt-12 flex w-full max-w-md gap-2">
        <Input placeholder="Enter your email..." type="email" />
        <Button>Subscribe</Button>
      </div>
    </section>
  )
}

Building a Dashboard Layout

import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Progress } from "@/components/ui/progress"

export default function Dashboard() {
  return (
    <div className="p-8">
      <div className="flex items-center justify-between">
        <h1 className="text-3xl font-bold">Dashboard</h1>
        <Button>Create New</Button>
      </div>

      <Tabs defaultValue="overview" className="mt-6">
        <TabsList>
          <TabsTrigger value="overview">Overview</TabsTrigger>
          <TabsTrigger value="analytics">Analytics</TabsTrigger>
          <TabsTrigger value="reports">Reports</TabsTrigger>
        </TabsList>
        <TabsContent value="overview" className="mt-6">
          <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
            <Card>
              <CardHeader>
                <CardTitle>Total Revenue</CardTitle>
              </CardHeader>
              <CardContent>
                <div className="text-2xl font-bold">$45,231.89</div>
                <p className="text-xs text-muted-foreground">
                  +20.1% from last month
                </p>
                <Progress value={60} className="mt-2" />
              </CardContent>
            </Card>
            {/* More cards... */}
          </div>
        </TabsContent>
      </Tabs>
    </div>
  )
}

Authentication Form

import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Separator } from "@/components/ui/separator"

export default function LoginForm() {
  return (
    <Card className="w-full max-w-md">
      <CardHeader>
        <CardTitle>Sign In</CardTitle>
        <CardDescription>
          Enter your email and password to access your account
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-4">
        <div className="space-y-2">
          <Label htmlFor="email">Email</Label>
          <Input id="email" type="email" placeholder="name@example.com" />
        </div>
        <div className="space-y-2">
          <Label htmlFor="password">Password</Label>
          <Input id="password" type="password" />
        </div>
        <Button className="w-full">Sign In</Button>
        <div className="relative">
          <Separator />
          <span className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 bg-background px-2 text-xs text-muted-foreground">
            OR CONTINUE WITH
          </span>
        </div>
        <Button variant="outline" className="w-full">
          GitHub
        </Button>
      </CardContent>
      <CardFooter className="flex justify-center">
        <p className="text-sm text-muted-foreground">
          Don't have an account? <a href="#" className="underline">Sign up</a>
        </p>
      </CardFooter>
    </Card>
  )
}

Troubleshooting

Components Don't Match Preview

Problem: Installed component looks different from the Better Design website preview.

Solutions:

  1. Ensure globals.css was updated by the CLI (check for CSS variables)
  2. Verify your Tailwind config includes shadcn color definitions
  3. Check that you're importing from the correct path: @/components/ui/[component]
  4. Clear Next.js cache: rm -rf .next and restart dev server

CSS Variables Not Applied

Problem: Components render but colors/spacing are wrong.

Solution: Check that globals.css is imported in your root layout:

// app/layout.tsx or pages/_app.tsx
import "@/app/globals.css"

Type Errors After Installation

Problem: TypeScript errors on component imports.

Solutions:

  1. Restart TypeScript server in your editor
  2. Check tsconfig.json has correct path alias:
{
  "compilerOptions": {
    "paths": {
      "@/*": ["./*"]
    }
  }
}
  1. Run npm install to ensure all dependencies are installed

Mixing Design Systems

Problem: Components from different design systems clash visually.

Best Practice: Stick to one design system per project for consistency. If you must mix:

  • Use different design systems for distinct sections (e.g., marketing site vs. app dashboard)
  • Test thoroughly in both light and dark modes
  • Be prepared to manually adjust CSS variables

Component Dependencies Missing

Problem: Error about missing component dependency (e.g., Button needs Label).

Solution: Install the missing component from the same design system:

npx shadcn@latest add https://www.better-design.com/registry/linear/label.json

The shadcn CLI usually handles dependencies automatically, but occasionally you may need to manually install related components.

Contributing

To contribute a new design system or component:

  1. Fork the repository: https://github.com/marvkr/better-design
  2. Create both registry/<design-system>/ and components/<design-system>/ directories
  3. Add component JSON files to registry/ following shadcn registry format
  4. Add matching .tsx files to components/<design-system>/components/ui/
  5. Include globals.css with theme CSS variables
  6. Update registry/index.json manifest
  7. Submit a pull request

All design systems must be MIT licensed and include at least 20+ core components.

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/reason-machines/design-skills/better-design-shadcn-themes">View better-design-shadcn-themes on skillZs</a>