| name | shadcn-ui | 
| description | Guide for implementing shadcn/ui - a collection of beautifully-designed, accessible UI components built with Radix UI and Tailwind CSS. Use when building user interfaces, adding UI components, or implementing design systems in React-based applications. | 
| license | MIT | 
| version | 1.0.0 | 
shadcn/ui Skill
shadcn/ui is a collection of beautifully-designed, accessible components and a code distribution platform built with TypeScript, Tailwind CSS, and Radix UI primitives. It's not a traditional component library but a collection of reusable components you can copy and paste into your apps.
Reference
https://ui.shadcn.com/llms.txt
When to Use This Skill
Use this skill when:
- Building user interfaces with React-based frameworks (Next.js, Vite, Remix, Astro, etc.)
 - Adding pre-built, accessible UI components to applications
 - Implementing design systems with Tailwind CSS
 - Setting up forms with validation (React Hook Form + Zod)
 - Adding data tables, charts, or complex UI patterns
 - Implementing dark mode with consistent theming
 - Customizing component appearance and behavior
 
Core Concepts
Key Principles
- Open Code: Copy components into your project, modify freely
 - Composition: Built with composable primitives from Radix UI
 - Distribution: Components distributed via CLI, not npm packages
 - Beautiful Defaults: Thoughtfully designed with excellent aesthetics
 - AI-Ready: Structured for easy integration with AI tools
 
Architecture
shadcn/ui follows a unique distribution model:
- CLI Tool: Installs and manages components via 
npx shadcn@latest - Component Registry: Central repository of components
 - Local Components: Components live in your 
components/ui/directory - Full Ownership: You own the code, modify as needed
 
Technology Stack
- TypeScript: Full type safety
 - Tailwind CSS: Utility-first styling (v3 and v4 support)
 - Radix UI: Accessible, unstyled primitives
 - Class Variance Authority: Component variants
 - React 19: Compatible with latest React
 
Installation & Setup
Initial Setup
Using the CLI (Recommended):
npx shadcn@latest init
The CLI will prompt for:
- Framework preference (Next.js, Vite, etc.)
 - TypeScript or JavaScript
 - Component installation location
 - CSS variables or Tailwind configuration
 - Color theme preferences
 - Global CSS file location
 
Manual Setup:
- Install dependencies:
 
npm install tailwindcss-animate class-variance-authority clsx tailwind-merge lucide-react
- Create 
components.json: 
{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "new-york",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "tailwind.config.ts",
    "css": "app/globals.css",
    "baseColor": "zinc",
    "cssVariables": true
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils"
  }
}
- Configure Tailwind:
 
// tailwind.config.ts
import type { Config } from "tailwindcss"
const config: Config = {
  darkMode: ["class"],
  content: [
    './pages/**/*.{ts,tsx}',
    './components/**/*.{ts,tsx}',
    './app/**/*.{ts,tsx}',
  ],
  theme: {
    extend: {},
  },
  plugins: [require("tailwindcss-animate")],
}
export default config
- Create utility file:
 
// lib/utils.ts
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}
Adding Components
Via CLI:
# Add single component
npx shadcn@latest add button
# Add multiple components
npx shadcn@latest add button card dialog
# Add all components
npx shadcn@latest add --all
What happens when you add a component:
- Component files are copied to 
components/ui/ - Dependencies are automatically installed
 - Component is ready to import and use
 
Component Categories
Form & Input Components
Button:
import { Button } from "@/components/ui/button"
<Button variant="default">Click me</Button>
<Button variant="destructive">Delete</Button>
<Button variant="outline" size="sm">Small</Button>
<Button variant="ghost" size="icon">
  <Icon />
</Button>
Input:
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
<div>
  <Label htmlFor="email">Email</Label>
  <Input id="email" type="email" placeholder="you@example.com" />
</div>
Form (with validation):
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import * as z from "zod"
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"
const formSchema = z.object({
  username: z.string().min(2).max(50),
  email: z.string().email(),
})
function ProfileForm() {
  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      username: "",
      email: "",
    },
  })
  function onSubmit(values: z.infer<typeof formSchema>) {
    console.log(values)
  }
  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
        <FormField
          control={form.control}
          name="username"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Username</FormLabel>
              <FormControl>
                <Input placeholder="shadcn" {...field} />
              </FormControl>
              <FormDescription>
                This is your public display name.
              </FormDescription>
              <FormMessage />
            </FormItem>
          )}
        />
        <Button type="submit">Submit</Button>
      </form>
    </Form>
  )
}
Select:
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
<Select>
  <SelectTrigger className="w-[180px]">
    <SelectValue placeholder="Theme" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="light">Light</SelectItem>
    <SelectItem value="dark">Dark</SelectItem>
    <SelectItem value="system">System</SelectItem>
  </SelectContent>
</Select>
Checkbox:
import { Checkbox } from "@/components/ui/checkbox"
import { Label } from "@/components/ui/label"
<div className="flex items-center space-x-2">
  <Checkbox id="terms" />
  <Label htmlFor="terms">Accept terms and conditions</Label>
</div>
Date Picker:
import { Calendar } from "@/components/ui/calendar"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { Button } from "@/components/ui/button"
import { CalendarIcon } from "lucide-react"
import { format } from "date-fns"
const [date, setDate] = useState<Date>()
<Popover>
  <PopoverTrigger asChild>
    <Button variant="outline">
      <CalendarIcon className="mr-2 h-4 w-4" />
      {date ? format(date, "PPP") : "Pick a date"}
    </Button>
  </PopoverTrigger>
  <PopoverContent className="w-auto p-0">
    <Calendar mode="single" selected={date} onSelect={setDate} />
  </PopoverContent>
</Popover>
Layout & Navigation
Card:
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
<Card>
  <CardHeader>
    <CardTitle>Card Title</CardTitle>
    <CardDescription>Card Description</CardDescription>
  </CardHeader>
  <CardContent>
    <p>Card Content</p>
  </CardContent>
  <CardFooter>
    <p>Card Footer</p>
  </CardFooter>
</Card>
Tabs:
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
<Tabs defaultValue="account">
  <TabsList>
    <TabsTrigger value="account">Account</TabsTrigger>
    <TabsTrigger value="password">Password</TabsTrigger>
  </TabsList>
  <TabsContent value="account">Account settings</TabsContent>
  <TabsContent value="password">Password settings</TabsContent>
</Tabs>
Accordion:
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion"
<Accordion type="single" collapsible>
  <AccordionItem value="item-1">
    <AccordionTrigger>Is it accessible?</AccordionTrigger>
    <AccordionContent>
      Yes. It adheres to the WAI-ARIA design pattern.
    </AccordionContent>
  </AccordionItem>
</Accordion>
Navigation Menu:
import {
  NavigationMenu,
  NavigationMenuContent,
  NavigationMenuItem,
  NavigationMenuLink,
  NavigationMenuList,
  NavigationMenuTrigger,
} from "@/components/ui/navigation-menu"
<NavigationMenu>
  <NavigationMenuList>
    <NavigationMenuItem>
      <NavigationMenuTrigger>Item One</NavigationMenuTrigger>
      <NavigationMenuContent>
        <NavigationMenuLink>Link</NavigationMenuLink>
      </NavigationMenuContent>
    </NavigationMenuItem>
  </NavigationMenuList>
</NavigationMenu>
Overlays & Dialogs
Dialog:
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"
<Dialog>
  <DialogTrigger asChild>
    <Button>Open Dialog</Button>
  </DialogTrigger>
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Are you sure?</DialogTitle>
      <DialogDescription>
        This action cannot be undone.
      </DialogDescription>
    </DialogHeader>
  </DialogContent>
</Dialog>
Drawer:
import {
  Drawer,
  DrawerClose,
  DrawerContent,
  DrawerDescription,
  DrawerFooter,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
} from "@/components/ui/drawer"
<Drawer>
  <DrawerTrigger>Open</DrawerTrigger>
  <DrawerContent>
    <DrawerHeader>
      <DrawerTitle>Are you sure?</DrawerTitle>
      <DrawerDescription>This action cannot be undone.</DrawerDescription>
    </DrawerHeader>
    <DrawerFooter>
      <Button>Submit</Button>
      <DrawerClose>Cancel</DrawerClose>
    </DrawerFooter>
  </DrawerContent>
</Drawer>
Popover:
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover"
<Popover>
  <PopoverTrigger>Open</PopoverTrigger>
  <PopoverContent>Place content here.</PopoverContent>
</Popover>
Toast:
import { useToast } from "@/hooks/use-toast"
import { Button } from "@/components/ui/button"
const { toast } = useToast()
<Button
  onClick={() => {
    toast({
      title: "Scheduled: Catch up",
      description: "Friday, February 10, 2023 at 5:57 PM",
    })
  }}
>
  Show Toast
</Button>
Command:
import {
  Command,
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from "@/components/ui/command"
<Command>
  <CommandInput placeholder="Type a command or search..." />
  <CommandList>
    <CommandEmpty>No results found.</CommandEmpty>
    <CommandGroup heading="Suggestions">
      <CommandItem>Calendar</CommandItem>
      <CommandItem>Search Emoji</CommandItem>
      <CommandItem>Calculator</CommandItem>
    </CommandGroup>
  </CommandList>
</Command>
Feedback & Status
Alert:
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
<Alert>
  <AlertTitle>Heads up!</AlertTitle>
  <AlertDescription>
    You can add components to your app using the CLI.
  </AlertDescription>
</Alert>
<Alert variant="destructive">
  <AlertTitle>Error</AlertTitle>
  <AlertDescription>
    Your session has expired. Please log in again.
  </AlertDescription>
</Alert>
Progress:
import { Progress } from "@/components/ui/progress"
<Progress value={33} />
Skeleton:
import { Skeleton } from "@/components/ui/skeleton"
<div className="flex items-center space-x-4">
  <Skeleton className="h-12 w-12 rounded-full" />
  <div className="space-y-2">
    <Skeleton className="h-4 w-[250px]" />
    <Skeleton className="h-4 w-[200px]" />
  </div>
</div>
Display Components
Table:
import {
  Table,
  TableBody,
  TableCaption,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"
<Table>
  <TableCaption>A list of your recent invoices.</TableCaption>
  <TableHeader>
    <TableRow>
      <TableHead>Invoice</TableHead>
      <TableHead>Status</TableHead>
      <TableHead>Amount</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>INV001</TableCell>
      <TableCell>Paid</TableCell>
      <TableCell>$250.00</TableCell>
    </TableRow>
  </TableBody>
</Table>
Data Table (with sorting/filtering):
npx shadcn@latest add data-table
Avatar:
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
<Avatar>
  <AvatarImage src="https://github.com/shadcn.png" />
  <AvatarFallback>CN</AvatarFallback>
</Avatar>
Badge:
import { Badge } from "@/components/ui/badge"
<Badge>Default</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="destructive">Destructive</Badge>
<Badge variant="outline">Outline</Badge>
Theming & Customization
Dark Mode Setup
Next.js (App Router):
- Install next-themes:
 
npm install next-themes
- Create theme provider:
 
// components/theme-provider.tsx
"use client"
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
export function ThemeProvider({
  children,
  ...props
}: React.ComponentProps<typeof NextThemesProvider>) {
  return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}
- Wrap app with provider:
 
// app/layout.tsx
import { ThemeProvider } from "@/components/theme-provider"
export default function RootLayout({ children }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <ThemeProvider
          attribute="class"
          defaultTheme="system"
          enableSystem
          disableTransitionOnChange
        >
          {children}
        </ThemeProvider>
      </body>
    </html>
  )
}
- Add theme toggle:
 
import { Moon, Sun } from "lucide-react"
import { useTheme } from "next-themes"
import { Button } from "@/components/ui/button"
export function ThemeToggle() {
  const { setTheme, theme } = useTheme()
  return (
    <Button
      variant="ghost"
      size="icon"
      onClick={() => setTheme(theme === "light" ? "dark" : "light")}
    >
      <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
      <Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
      <span className="sr-only">Toggle theme</span>
    </Button>
  )
}
Color Customization
Using CSS Variables:
/* 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%;
    --secondary-foreground: 222.2 47.4% 11.2%;
    --muted: 210 40% 96.1%;
    --muted-foreground: 215.4 16.3% 46.9%;
    --accent: 210 40% 96.1%;
    --accent-foreground: 222.2 47.4% 11.2%;
    --destructive: 0 84.2% 60.2%;
    --destructive-foreground: 210 40% 98%;
    --border: 214.3 31.8% 91.4%;
    --input: 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%;
    /* ... */
  }
}
Using Tailwind Config:
// tailwind.config.ts
export default {
  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))",
        },
        // ...
      },
    },
  },
}
Component Customization
Since components live in your codebase, you can modify them directly:
// components/ui/button.tsx
// Modify variants, add new ones, change styles
const buttonVariants = cva(
  "inline-flex items-center justify-center rounded-md text-sm font-medium",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground",
        destructive: "bg-destructive text-destructive-foreground",
        outline: "border border-input bg-background",
        // Add custom variant
        custom: "bg-gradient-to-r from-purple-500 to-pink-500 text-white",
      },
      size: {
        default: "h-10 px-4 py-2",
        sm: "h-9 rounded-md px-3",
        lg: "h-11 rounded-md px-8",
        // Add custom size
        xl: "h-14 rounded-md px-10 text-lg",
      },
    },
    defaultVariants: {
      variant: "default",
      size: "default",
    },
  }
)
Advanced Patterns
Server Actions (Next.js)
// app/actions.ts
"use server"
import { z } from "zod"
const schema = z.object({
  email: z.string().email(),
  password: z.string().min(8),
})
export async function createUser(formData: FormData) {
  const validatedFields = schema.safeParse({
    email: formData.get("email"),
    password: formData.get("password"),
  })
  if (!validatedFields.success) {
    return {
      errors: validatedFields.error.flatten().fieldErrors,
    }
  }
  // Create user
}
// app/signup/page.tsx
import { createUser } from "@/app/actions"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
export default function SignupPage() {
  return (
    <form action={createUser}>
      <Input name="email" type="email" />
      <Input name="password" type="password" />
      <Button type="submit">Sign up</Button>
    </form>
  )
}
Reusable Form Patterns
// lib/form-utils.ts
import { UseFormReturn } from "react-hook-form"
import { FormField, FormItem, FormLabel, FormControl, FormMessage } from "@/components/ui/form"
import { Input } from "@/components/ui/input"
export function TextFormField({
  form,
  name,
  label,
  placeholder,
  type = "text",
}: {
  form: UseFormReturn<any>
  name: string
  label: string
  placeholder?: string
  type?: string
}) {
  return (
    <FormField
      control={form.control}
      name={name}
      render={({ field }) => (
        <FormItem>
          <FormLabel>{label}</FormLabel>
          <FormControl>
            <Input type={type} placeholder={placeholder} {...field} />
          </FormControl>
          <FormMessage />
        </FormItem>
      )}
    />
  )
}
Responsive Component Composition
import { useMediaQuery } from "@/hooks/use-media-query"
import { Dialog, DialogContent } from "@/components/ui/dialog"
import { Drawer, DrawerContent } from "@/components/ui/drawer"
export function ResponsiveDialog({ children, ...props }) {
  const isDesktop = useMediaQuery("(min-width: 768px)")
  if (isDesktop) {
    return (
      <Dialog {...props}>
        <DialogContent>{children}</DialogContent>
      </Dialog>
    )
  }
  return (
    <Drawer {...props}>
      <DrawerContent>{children}</DrawerContent>
    </Drawer>
  )
}
Best Practices
- Use TypeScript: Leverage full type safety for better DX
 - Customize Components: Modify components directly in your codebase
 - Compose Primitives: Build complex UIs by composing simple components
 - Follow Accessibility: Components are built on accessible Radix UI primitives
 - Use Form Validation: Integrate React Hook Form + Zod for robust forms
 - Dark Mode: Implement theme switching for better UX
 - Responsive Design: Use Tailwind responsive utilities
 - Performance: Use code splitting and lazy loading for large component sets
 - Consistent Spacing: Use Tailwind spacing scale consistently
 - Icon Library: Use lucide-react for consistent icons
 
Framework-Specific Setup
Next.js
- Support for App Router and Pages Router
 - Server Components compatibility
 - Server Actions integration
 
Vite
- Fast development with HMR
 - Easy setup with TypeScript
 
Remix
- Route-based architecture
 - Progressive enhancement
 
Astro
- Static site generation
 - Islands architecture
 
Laravel (Inertia.js)
- Backend integration with Laravel
 - React frontend with Inertia
 
Common Patterns
Loading States
import { Skeleton } from "@/components/ui/skeleton"
export function UserCardSkeleton() {
  return (
    <div className="flex items-center space-x-4">
      <Skeleton className="h-12 w-12 rounded-full" />
      <div className="space-y-2">
        <Skeleton className="h-4 w-[250px]" />
        <Skeleton className="h-4 w-[200px]" />
      </div>
    </div>
  )
}
export function UserCard({ user }: { user?: User }) {
  if (!user) return <UserCardSkeleton />
  return (
    <div className="flex items-center space-x-4">
      <Avatar>
        <AvatarImage src={user.avatar} />
        <AvatarFallback>{user.initials}</AvatarFallback>
      </Avatar>
      <div>
        <p className="text-sm font-medium">{user.name}</p>
        <p className="text-sm text-muted-foreground">{user.email}</p>
      </div>
    </div>
  )
}
Error Handling
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
import { AlertCircle } from "lucide-react"
export function ErrorAlert({ error }: { error: Error }) {
  return (
    <Alert variant="destructive">
      <AlertCircle className="h-4 w-4" />
      <AlertTitle>Error</AlertTitle>
      <AlertDescription>{error.message}</AlertDescription>
    </Alert>
  )
}
Confirmation Dialogs
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog"
export function DeleteConfirmation({ onConfirm }: { onConfirm: () => void }) {
  return (
    <AlertDialog>
      <AlertDialogTrigger asChild>
        <Button variant="destructive">Delete</Button>
      </AlertDialogTrigger>
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
          <AlertDialogDescription>
            This action cannot be undone. This will permanently delete your
            account and remove your data from our servers.
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel>Cancel</AlertDialogCancel>
          <AlertDialogAction onClick={onConfirm}>Continue</AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  )
}
Troubleshooting
Common Issues
"Module not found" errors
- Check path aliases in 
tsconfig.json - Verify 
components.jsonaliases match your project structure - Ensure components are installed in correct directory
 
- Check path aliases in 
 Styling not applied
- Verify Tailwind CSS is configured correctly
 - Check 
globals.cssimports CSS variables - Ensure 
tailwindcss-animateplugin is installed 
Dark mode not working
- Check ThemeProvider is wrapping your app
 - Verify 
suppressHydrationWarningon<html>tag - Ensure dark mode classes are defined in CSS
 
Form validation issues
- Install required packages: 
react-hook-form,@hookform/resolvers,zod - Check schema matches form fields
 - Verify resolver is configured correctly
 
- Install required packages: 
 TypeScript errors
- Update 
@types/reactand@types/react-dom - Check component prop types
 - Ensure TypeScript version is compatible (>= 4.5)
 
- Update 
 
Resources
- Documentation: https://ui.shadcn.com
 - GitHub: https://github.com/shadcn-ui/ui
 - Component Registry: https://ui.shadcn.com/docs/components
 - Examples: https://ui.shadcn.com/examples
 - Figma Design Kit: https://ui.shadcn.com/figma
 - v0 (AI UI Generator): https://v0.dev
 
Implementation Checklist
When implementing shadcn/ui:
-  Run 
npx shadcn@latest initto set up project - Configure Tailwind CSS and path aliases
 - Set up dark mode with ThemeProvider
 - Install required components via CLI
 - Create utility functions (cn helper)
 - Set up form handling (React Hook Form + Zod)
 - Configure icons (lucide-react)
 - Implement theme toggle component
 - Test components in both light and dark modes
 - Customize color palette if needed
 - Add loading states with Skeleton
 - Implement error handling patterns
 - Test accessibility features
 - Optimize bundle size (tree-shaking)
 - Add responsive design utilities