- Accordion
- Action Bar
- Alert Dialog
- Alert
- Announcement
- Aspect Ratio
- Autocomplete
- Avatar
- Badge
- Bottom Navigation
- Breadcrumb
- Button Group
- Button
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Circular Progress
- Circular Slider
- Clipboard
- Collapsible
- Color Picker
- Combobox
- Command
- Context Menu
- Data List
- Date Picker
- Dialog
- Drawer
- Editable
- Field
- File Upload
- Float
- Floating Panel
- Frame
- Hint
- Hover Card
- Image Cropper
- Input Group
- Input OTP
- Input
- Item
- Kbd
- Link Overlay
- Listbox
- Marquee
- Menu
- Native Select
- Number Input
- Pagination
- Popover
- Progress
- Prose
- QR Code
- Radio Group
- Rating
- Resizable
- Scroll Area
- Segment Group
- Select
- Separator
- Sheet
- Sidebar
- Signature Pad
- Skeleton
- Skip Nav
- Slider
- Spinner
- Status
- Steps
- Switch
- Table
- Tabs
- Textarea
- Timer
- Toast
- Toggle Group
- Toggle Tooltip
- Toggle
- Tooltip
- Tour
- Tree View
Manual Installation
Install Shark UI without the shadcn CLI by copying config and files manually.
Manual setup gives you full control over every file. Use this when the CLI does not fit your setup or you prefer not to use it.
Add Tailwind CSS
Components are styled with Tailwind CSS. Install it first:
Follow the Tailwind CSS installation instructions.
Add dependencies
Install the packages Shark UI components use:
pnpm add tailwind-variants clsx tailwind-merge lucide-react tw-animate-css
Configure path aliases
Configure the path aliases in your tsconfig.json file.
{ "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["./*"] } } }
The @ alias is a convention; you can use a different alias if needed.
Configure styles
Create a file styles/globals.css with the following. This defines the design tokens (colors, radius, animations) that components depend on. See Styling and Colors for how the system fits together and a full variable reference.
@import "tailwindcss"; @import "tw-animate-css"; @custom-variant dark (&:is(.dark *)); @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-secondary: var(--secondary); --color-secondary-foreground: var(--secondary-foreground); --color-card: var(--card); --color-card-foreground: var(--card-foreground); --color-popover: var(--popover); --color-popover-foreground: var(--popover-foreground); --color-muted: var(--muted); --color-muted-foreground: var(--muted-foreground); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-success: var(--success); --color-success-foreground: var(--success-foreground); --color-info: var(--info); --color-info-foreground: var(--info-foreground); --color-warning: var(--warning); --color-warning-foreground: var(--warning-foreground); --color-destructive: var(--destructive); --color-destructive-foreground: var(--destructive-foreground); --color-border: var(--border); --color-input: var(--input); --color-ring: var(--ring); --color-chart-1: var(--chart-1); --color-chart-2: var(--chart-2); --color-chart-3: var(--chart-3); --color-chart-4: var(--chart-4); --color-chart-5: var(--chart-5); --radius: var(--radius); --radius-xs: calc(var(--radius) - 8px); --radius-sm: calc(var(--radius) - 4px); --radius-md: var(--radius); --radius-lg: calc(var(--radius) + 4px); --radius-xl: calc(var(--radius) + 8px); --radius-2xl: calc(var(--radius) + 16px); --radius-3xl: calc(var(--radius) + 24px); --radius-4xl: calc(var(--radius) + 32px); } :root { --radius: 0.25rem; --background: var(--color-white); --foreground: var(--color-neutral-950); --card: var(--color-white); --card-foreground: var(--color-neutral-950); --popover: var(--color-white); --popover-foreground: var(--color-neutral-950); --primary: var(--color-neutral-900); --primary-foreground: var(--color-neutral-50); --secondary: var(--color-neutral-100); --secondary-foreground: var(--color-neutral-900); --muted: var(--color-neutral-100); --muted-foreground: var(--color-neutral-500); --accent: var(--color-neutral-100); --accent-foreground: var(--color-neutral-900); --success: var(--color-emerald-600); --success-foreground: var(--color-green-50); --info: var(--color-sky-600); --info-foreground: var(--color-sky-50); --warning: var(--color-yellow-400); --warning-foreground: var(--color-yellow-950); --destructive: var(--color-red-600); --destructive-foreground: var(--color-red-50); --border: var(--color-neutral-200); --input: var(--color-neutral-300); --ring: var(--color-primary); --chart-1: var(--color-orange-600); --chart-2: var(--color-teal-600); --chart-3: var(--color-cyan-900); --chart-4: var(--color-amber-400); --chart-5: var(--color-amber-500); } .dark { --background: var(--color-neutral-950); --foreground: var(--color-neutral-50); --card: var(--color-neutral-950); --card-foreground: var(--color-neutral-50); --popover: var(--color-neutral-950); --popover-foreground: var(--color-neutral-50); --primary: var(--color-neutral-50); --primary-foreground: var(--color-neutral-900); --secondary: var(--color-neutral-800); --secondary-foreground: var(--color-neutral-50); --muted: var(--color-neutral-900); --muted-foreground: var(--color-neutral-400); --accent: var(--color-neutral-800); --accent-foreground: var(--color-neutral-50); --success: var(--color-emerald-600); --success-foreground: var(--color-green-50); --info: var(--color-sky-600); --info-foreground: var(--color-sky-50); --warning: var(--color-yellow-600); --warning-foreground: var(--color-yellow-50); --destructive: var(--color-red-700); --destructive-foreground: var(--color-red-50); --border: var(--color-neutral-800); --input: var(--color-neutral-800); --ring: var(--color-primary); --chart-1: var(--color-blue-700); --chart-2: var(--color-emerald-500); --chart-3: var(--color-amber-500); --chart-4: var(--color-purple-500); --chart-5: var(--color-rose-500); } @layer base { ::selection { @apply bg-primary/80 text-primary-foreground; } * { @apply border-border outline-ring/50; } html { @apply antialiased scroll-smooth; } body { @apply bg-background text-foreground flex min-h-svh flex-col; } main { @apply flex-1 flex flex-col; } }
Add a cn helper
import { type ClassValue, clsx } from "clsx" import { twMerge } from "tailwind-merge" export const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs))
Create a components.json file
Create a components.json file in the project root so the shadcn CLI (if you use it later) knows where to write components.
{ "$schema": "https://ui.shadcn.com/schema.json", "style": "new-york", "rsc": false, "tsx": true, "tailwind": { "config": "", "css": "src/styles/globals.css", "baseColor": "neutral", "cssVariables": true, "prefix": "" }, "aliases": { "components": "@/components", "utils": "@/lib/utils", "ui": "@/components/ui", "lib": "@/lib", "hooks": "@/hooks" }, "iconLibrary": "lucide" }
Next steps
You can now add components manually from the component docs or use the CLI with pnpm dlx shadcn@latest add https://shark.vini.one/r/button.json to fetch and install them.