Migrate from shadcn/ui
WunderUI is built the way a shadcn/ui project already works, so most of your setup carries over. This page shows what stays, what changes, and how to move one page at a time while both libraries run side by side.
At a glance
What you can keep:
| Shared | In WunderUI |
|---|---|
| Source you own | The 83 free components are MIT source. writes them into , like the shadcn CLI. |
| Tailwind CSS v4 | CSS-first setup with @theme, no tailwind.config.js. |
| Base UI | The primitives come from , so the Base UI flavour of shadcn/ui is the closest match. |
| cn() | The same helper name in , taught WunderUI's own utilities (see Pitfalls). |
| data-slot | Every part carries , so selectors such as keep working. |
| CSS variables | The shadcn/ui token names exist with the same meaning, light under and dark under . |
| lucide-react | The icon set the components use. |
What is different:
| Area | In WunderUI |
|---|---|
| Tokens | More of them: text levels, link, control borders, tints, a brand scale. See Theming. |
| Density | Control heights, row padding and card padding are tokens with a compact default and a comfortable mode. |
| Design source | A Figma library with the same names, variants and tokens as the code. |
| Motion | Named duration and easing tokens (, ) and rules for what may move. See Motion. |
| Agents | DESIGN.md, design.json, an MCP server and a CLI that answers questions offline. See Build with AI. |
| Scope | Charts, data tables, AI and agent components in Core and Pro; whole screens as UI Blocks with Pro. |
1. Install WunderUI Free
Two ways in. The CLI writes components as source, exactly like the shadcn CLI does. The package keeps them in , which is the easier route while both libraries live in one app.
npx wunderui-cli add button card dialogOr install the Free package:
npm install @wunderui/reactThe npm package is WunderUI Free and holds the free components only. Core and Pro come from a private repository; Installation shows how.
2. Wire up the styles
Import WunderUI after Tailwind and point at the components. With the CLI that is the files it wrote; with the package, its folder:
/* app/globals.css */
@import "tailwindcss";
@import "tw-animate-css";
@import "@wunderui/react/styles.css"; /* CLI: "../styles/wunderui.css" */
@source "../node_modules/@wunderui/react/dist"; /* CLI: "../components" */
/* your shadcn/ui :root, .dark and @theme inline blocks follow here */The later definition wins
shadcn/ui and WunderUI define the same variable names, and has to come first, so the blocks in your own file override WunderUI's values: WunderUI components then render in your shadcn/ui colours and radius. Delete your , and blocks once you want WunderUI's look everywhere; both libraries switch together.
3. Map your theme
Every shadcn/ui variable has a WunderUI counterpart under the same name, so a theme you wrote for shadcn/ui keeps working. The values and a few roles differ:
| shadcn/ui variable | WunderUI |
|---|---|
| Same names. Layouts put cards on --bg-page, a tinted canvas in light mode. | |
| Same names and roles. | |
| Same names. Primary reads from the brand scale --brand-50 … --brand-1000 (indigo by default); change the scale to rebrand. | |
| Same names, equal to the card colour. The plain button uses --card and --border-control. | |
| Same names. Two more text levels: --text-secondary and --text-tertiary. | |
| Same names, equal to muted. | |
| Same name, alias --error. --destructive-foreground is kept. | |
| Same name, for dividers and card outlines. Controls use --border-control. | |
| Same name. Light: equal to --border-control; dark: a darker grey at 3:1. | |
| Same name, drawn as a 1 px focus line in the brand colour. | |
| Same name, 0.75rem. Only rounded-3xl and rounded-4xl derive from it (see Pitfalls). | |
| All five, --chart-1 to --chart-5: brand indigo first, then cool neighbours, grey last. | |
| Same eight names, including --sidebar-ring. |
New on top: , , , the text tones , and , nine fills, and the density and motion tokens. The Theme Builder writes a brand theme from one colour.
4. Map your components
The shadcn/ui components and their WunderUI counterparts. Notes cover the free components; Core and Pro components are listed by name.
| shadcn/ui → WunderUI | What changes |
|---|---|
| AccordionAccordion | Same idea and parts. |
| AlertAlert | is a tone: plain (default), primary, positive, negative, warning; plus small or large. |
| Alert DialogAlert Dialog | Same parts, plus . |
| Aspect RatioNo counterpart | No component. Use Tailwind's or . |
| AvatarAvatarAvatar Group | Sizes xs to xl, circle or square, a for the fallback. |
| BadgeBadge | No : pick a (12, default blue) and a (plain, light, ghost and three border styles). |
| BreadcrumbBreadcrumb | Same idea and parts. |
| ButtonButtonIcon Button | becomes , becomes ; outline, ghost, destructive and link keep their names. Sizes run sm to 2xl (default md). Icon-only buttons are , not . |
| Button GroupButton Group | Same idea and parts. |
| CalendarCalendar | Built in, without react-day-picker, so its props differ. |
| CardCard | Same parts plus ; 16 px corners and padding from the density tokens. |
| CarouselCarousel | Built in, without Embla. |
| ChartArea ChartBar ChartLine ChartPie Chart | Included in Core and Pro. |
| CheckboxCheckbox | Same idea and parts. |
| CollapsibleCollapsible | Same idea and parts. |
| ComboboxCombobox | Same idea and parts. |
| CommandCommand | Included in Core and Pro. |
| Context MenuContext Menu | Included in Core and Pro. |
| Data TableData TableData Grid | Included in Core and Pro. |
| Date PickerDate Picker | One component (a Calendar in a Popover with Cancel and Apply), not a recipe to assemble. |
| DialogDialog | Same parts, plus . |
| DrawerSheet | No Vaul drawer: use with . |
| Dropdown MenuDropdown Menu | Included in Core and Pro. |
| EmptyEmpty State | One component, , with a (default dashed) instead of composed parts. |
| FieldFieldFieldset | , , , on Base UI Field; groups use . |
| Hover CardHover Card | Same idea and parts. |
| InputInput | Height comes from the density tokens: 36 px by default. |
| Input GroupInput Group | Two parts: and . |
| Input OTPOTP Field | and on Base UI, without the input-otp package. |
| ItemItem CardSelector Item | for a row card; for a row with a radio, checkbox or switch. |
| KbdKbd | Same idea and parts. |
| LabelLabel | Same idea and parts. |
| MenubarNo counterpart | No equivalent. Toolbar groups buttons and links. |
| Native SelectNo counterpart | No styled native . Use Native Select (see Select). |
| Navigation MenuNavbar | Included in Core and Pro. |
| PaginationPagination | Also for previous and next only. |
| PopoverPopover | Same idea and parts. |
| ProgressProgress | Same idea and parts. |
| Radio GroupRadio GroupRadio Button Group | Same idea and parts. |
| ResizableResizable | Included in Core and Pro. |
| Scroll AreaScroll Area | Included in Core and Pro. |
| SelectNative SelectInline Select | Despite its name, is a Base UI Select with a styled popup. sits inside a sentence. |
| SeparatorSeparatorDivider with Label | Same idea and parts. |
| SheetSheet | is right (default), left or bottom. |
| SidebarSidebar | Included in Core and Pro. |
| SkeletonSkeleton | A for title, text, avatar or block. |
| SliderSlider | Same idea and parts. |
| Sonner / ToastToast | Base UI Toast instead of Sonner: wrap the app in and call . |
| SpinnerSpinner | Same idea and parts. |
| SwitchSwitch | Same idea and parts. |
| TableTable | Same parts plus ready-made cell types. Sorting and filtering live in Data Table. |
| TabsTabs | Adds . |
| TextareaTextarea | Same idea and parts. |
| ToggleToggle | Same idea and parts. |
| Toggle GroupRadio Button GroupCheckbox Button Group | Two components: one choice or several. |
| TooltipTooltip | Same idea and parts. |
| TypographyNo counterpart | No component. See Typography for the text styles. |
5. Migrate step by step
- Run both. Install the package and keep your folder. The import path tells them apart; alias where a file needs both:
import { Button } from "@/components/ui/button" // shadcn/ui
import { Button as WButton, Card } from "@wunderui/react" // WunderUI- Keep one theme. While your token blocks stay in , both libraries share your shadcn/ui colours, so mixed pages look consistent.
- Switch page by page. Change the imports of one route, adjust the props from the table above ( → , → ), check it in light and dark, then move on.
- Remove what is unused. When nothing imports a shadcn/ui file any more, delete it, and its dependencies with it (for example , or once nothing uses them).
- Hand over the theme. Delete your own , and blocks, or keep only the brand values you want on top. Your Tailwind setup, and the class switch stay as they are.
Moving to the CLI later
writes to and skips files that already exist. To replace a shadcn/ui file with the WunderUI one, delete it first or pass , then fix the props wherever it is imported.
6. Pitfalls
| Watch out for | Why |
|---|---|
| Focus and borders | Focus is a 1 px line (an outline on buttons, the border on fields), not a wide translucent ring. Control rims use ; is the lighter divider grey. |
| Radius | to are fixed: 4, 8, 12, 16 and 24 px. Cards use 16 px. Changing only moves the two largest steps. |
| Density | Buttons and fields default to the compact scale (36 px at size md). Set for the roomier sizes; see Density. |
| Motion | is still loaded, so your classes work. New code uses the tokens: to and , , . |
| 16 px fields on phones | On touch screens and below 640 px, inputs, selects and textareas render at 16 px so iOS Safari does not zoom on focus. |
| Palette names | WunderUI redefines Tailwind's blue, indigo, purple, pink, red, orange, yellow and green with its own 100–1000 scales, so changes colour after the import. |
| cn() in lib/utils.ts | WunderUI's knows its own utilities (, , , gradients). The CLI does not replace an existing ; swap it so class merging stays correct. |
| Dark mode | The same class, for example from next-themes with . WunderUI's variant also respects a nested section; a later in your file replaces it. |
| Tailwind version | Tailwind v4 is required; there is no v3 build. |
| Icons | lucide-react, as in shadcn/ui. Keep one icon set per surface. |
7. Let your agent help
Give your coding agent the WunderUI context before it rewrites imports, so it uses the real props instead of the shadcn/ui ones it remembers:
claude mcp add wunderui -- npx -y wunderui-mcp
npx skills add wunder-ui/wunderuiThe MCP server answers component and token questions while the agent works, and DESIGN.md carries the rules in one file.
Coming with wunderui-cli 1.1
checks the package and its edition, the styles import and path, tokens, DESIGN.md, the MCP server and ThemeProvider; shows safe changes. prints a component's props for an agent. Both need wunderui-cli 1.1 or newer.