Manages shadcn-svelte components and projects — adding, updating, fixing, debugging, styling, and composing UI. Provides project context, component docs, and usage examples. Applies when working with shadcn-svelte, the CLI, design-system presets, or any project with a components.json file. Also triggers for "shadcn-svelte init", "add component", or registry URLs.
A framework for building UI, components, and design systems for Svelte. Components are added as source to the user's project via the CLI.
IMPORTANT: Run all CLI commands using the project's package runner:
npx shadcn-svelte@latest,pnpm dlx shadcn-svelte@latest, orbunx --bun shadcn-svelte@latest— based on the project's package manager. Examples below usenpx shadcn-svelte@latestbut substitute the correct runner for the project.
Read components.json at the project root and, when you need the live file layout, list the directory given by the aliases.ui path (resolved with the same rules as the CLI).
Each component lives in its own folder with an index.ts barrel. Match the installation docs:
import * as Dialog from "$lib/components/ui/dialog" then Dialog.Content, Dialog.Title, Card.Root, Card.Header, etc. — whatever the barrel exports (short names and/or Root as … aliases).import { Button } from "$lib/components/ui/button" and <Button>, not import * as Button + Button.Root. Same pattern for { Input }, { Badge }, { Spinner }, { Checkbox }, { Separator }, { Skeleton }, etc.import * as Dialog from "$lib/components/ui/dialog";
import { Button } from "$lib/components/ui/button";
import { Separator } from "$lib/components/ui/separator";
Use the real aliases from components.json (often $lib/components/ui/...), not hardcoded paths.
npx shadcn-svelte@latest add with no arguments to browse available components, or check Components before writing custom UI.variant="outline", size="sm", etc.bg-primary, text-muted-foreground — never raw values like bg-blue-500.These rules are always enforced. Each links to a file with Incorrect/Correct code pairs.
class for layout, not styling. Never override component colors or typography.space-x-* or space-y-*. Use flex with gap-*. For vertical stacks, flex flex-col gap-*.size-* when width and height are equal. size-10 not w-10 h-10.truncate shorthand. Not overflow-hidden text-ellipsis whitespace-nowrap.dark: color overrides. Use semantic tokens (bg-background, text-muted-foreground).cn() for conditional classes. Don't write manual template literal ternaries.z-index on overlay components. Dialog, Sheet, Popover, etc. handle their own stacking.Field.FieldGroup + Field.Field. Never use raw div with space-y-* or grid gap-* for form layout.InputGroup uses InputGroup.Input/InputGroup.Textarea. Never raw Input/Textarea inside InputGroup.Root.InputGroup.Root + InputGroup.Addon.ToggleGroup. Don't loop Button with manual active state.Field.FieldSet + Field.FieldLegend for grouping related checkboxes/radios. Don't use a div with a heading.data-invalid + aria-invalid. data-invalid on Field, aria-invalid on the control. For disabled: data-disabled on Field, disabled on the control.Select.Item → Select.Group. DropdownMenu.Item → DropdownMenu.Group. Command.Item → Command.Group.Dialog.Trigger / AlertDialog.Trigger, or control open state with bind:open on the root — see component docs.Dialog.Title, Sheet.Title, Drawer.Title required for accessibility. Use class="sr-only" if visually hidden.Card.Header/Card.Title/Card.Description/Card.Content/Card.Footer. Don't dump everything in Card.Content.isPending/isLoading. Compose with Spinner inside Button + disabled; use data-icon="inline-start" / inline-end on Spinner for correct spacing (import { Button }, import { Spinner }).Tabs.Trigger must be inside Tabs.List. Never render triggers directly in Tabs.Avatar always needs Avatar.Fallback. For when the image fails to load.div.Alert. Don't build custom styled divs.Empty. Don't build custom empty state markup.svelte-sonner. Use toast() from svelte-sonner with the Sonner component from your UI folder.Separator instead of <hr> or a div with border-only classes.Skeleton for loading placeholders. No custom animate-pulse divs.Badge instead of custom styled spans.<Button> use data-icon. data-icon="inline-start" or data-icon="inline-end" on the icon.size-4 or w-4 h-4.iconLibrary (e.g. @lucide/svelte), not string keys.npx shadcn-svelte@latest init --preset <code>.These are the most common patterns that differentiate correct shadcn-svelte code. For edge cases, see the linked rule files above.
<script lang="ts">
import * as Field from "$lib/components/ui/field";
import { Input } from "$lib/components/ui/input";
import { Button } from "$lib/components/ui/button";
import SearchIcon from "@lucide/svelte/icons/search";
import { Badge } from "$lib/components/ui/badge";
import * as Avatar from "$lib/components/ui/avatar";
</script>
<!-- Form layout: Field.FieldGroup + Field.Field, not div + Label. -->
<Field.FieldGroup>
<Field.Field>
<Field.FieldLabel for="email">Email</Field.FieldLabel>
<Input id="email" />
</Field.Field>
</Field.FieldGroup>
<!-- Validation: data-invalid on Field, aria-invalid on the control. -->
<Field.Field data-invalid>
<Field.FieldLabel for="email">Email</Field.FieldLabel>
<Input id="email" aria-invalid />
<Field.FieldDescription>Invalid email.</Field.FieldDescription>
</Field.Field>
<!-- Icons in buttons: data-icon, no sizing classes. -->
<Button>
<SearchIcon data-icon="inline-start" />
Search
</Button>
<!-- Spacing: gap-*, not space-y-*. -->
<div class="flex flex-col gap-4"></div>
<!-- Equal dimensions: size-*, not w-* h-*. -->
<Avatar.Root class="size-10">
<Avatar.Image src="/u.png" alt="User" />
<Avatar.Fallback>U</Avatar.Fallback>
</Avatar.Root>
<!-- Status colors: Badge variants or semantic tokens, not raw colors. -->
<Badge variant="secondary">+20.1%</Badge>
| Need | Use |
|---|---|
| Button/action | Button with appropriate variant (import { Button }) |
| Form inputs | Input, Select, Combobox, Switch, Checkbox, RadioGroup, Textarea, InputOTP, Slider |
| Toggle between 2–5 options | ToggleGroup.Root + ToggleGroup.Item |
| Data display | Table, Card, Badge, Avatar |
| Navigation | Sidebar, NavigationMenu, Breadcrumb, Tabs, Pagination |
| Overlays | Dialog (modal), Sheet (side panel), Drawer (bottom sheet), AlertDialog (confirmation) |
| Feedback | svelte-sonner (toast), Alert, Progress, Skeleton, Spinner |
| Command palette | Command inside Dialog |
| Charts | Chart (LayerChart) |
| Layout | Card, Separator, Resizable, ScrollArea, Accordion, Collapsible |
| Empty states | Empty |
| Menus | DropdownMenu, ContextMenu, Menubar |
| Tooltips/info | Tooltip, HoverCard, Popover |
Use components.json and the filesystem — not a separate info command:
aliases → use the actual alias prefix from config (e.g. $lib/), never hardcode unrelated projects.tailwind.css → the global CSS file where theme variables live. Edit this file for theme tweaks; don't add a second globals file unless the user already uses one.style → visual treatment (e.g. nova, vega, …) and registry style path.iconLibrary → determines icon packages (@lucide/svelte, @tabler/icons-svelte, etc.). Never assume @lucide/svelte.registry → where the CLI fetches components; default official registry at shadcn-svelte.com.resolvedPaths (conceptual) → the CLI resolves aliases to absolute paths; list aliases.ui on disk to see installed components.See cli.md for commands and flags.
Open https://shadcn-svelte.com/docs/components/<name>.md for docs and examples. When creating, fixing, debugging, or using a component, read the official page first so you follow the documented APIs.
components.json and list the UI components directory when needed.add, list files under the resolved ui path. Don't import components that haven't been added, and don't re-add ones already present unless updating.npx shadcn-svelte@latest add with no arguments (interactive list), or the docs site.npx shadcn-svelte@latest add <name> or a registry URL. To refresh existing files from the registry, use npx shadcn-svelte@latest update (see cli.md).aliases. Rewrite imports to use the project's ui / lib aliases from components.json.iconLibrary.add.Use the update command to pull the latest registry versions of components already in the project. Review changes with git diff after update.
npx shadcn-svelte@latest update [component] or --all.--overwrite on add without the user's explicit approval when it would destroy intentional edits.# Initialize shadcn-svelte in your project.
npx shadcn-svelte@latest init
# Initialize with a preset string from the docs site builder.
npx shadcn-svelte@latest init --preset <code>
# Add components (interactive when run with no names).
npx shadcn-svelte@latest add
npx shadcn-svelte@latest add button card dialog
npx shadcn-svelte@latest add --all
# Update components already installed.
npx shadcn-svelte@latest update button
npx shadcn-svelte@latest update --all --yes
# Build a custom registry (registry authors).
npx shadcn-svelte@latest registry build
Registry: default https://shadcn-svelte.com/registry — override in components.json if needed.
Docs: shadcn-svelte.com