shadcn.io is an independent project built on shadcn/ui
Next.js is the most common home for these components: the App Router, Server Components, and Tailwind CSS v4 out of the box. Start a new app with our preset, or add it to one you already have.
Create a new app
Run init with the Next.js template
The CLI asks for a project name, creates the app from shadcn's Next.js starter (Next.js 16, React 19, TypeScript, Tailwind CSS v4, dark mode with next-themes), then applies our preset: the theme in app/globals.css, lib/utils.ts, components.json and the packages.
For a monorepo, with the app in apps/web and the components in packages/ui:
Add a component
In a monorepo, run it from apps/web, or pass -c apps/web from the root.
Use it
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
export default function Home() {
return (
<main className="flex min-h-svh items-center justify-center p-6">
<Card className="w-full max-w-sm">
<CardHeader>
<CardTitle>Project overview</CardTitle>
<CardDescription>Track progress and recent activity.</CardDescription>
</CardHeader>
<CardContent>Your design system is ready.</CardContent>
</Card>
</main>
);
}In a monorepo, edit apps/web/app/page.tsx and import from @workspace/ui/components/card.
Add it to an existing app
Create the app, if you need one
bunx --bun create-next-app@latestTake the recommended defaults: TypeScript, Tailwind CSS, the App Router and the @/* import alias. With --src-dir, the app lives in src/app and @/* points at ./src/*.
Check Tailwind CSS and the alias
An app made with create-next-app has both. An older one needs Tailwind CSS v4 (tailwindcss and @tailwindcss/postcss, with @import "tailwindcss"; at the top of app/globals.css, as Tailwind's Next.js guide (opens in a new tab) shows) and the alias in tsconfig.json:
{
"compilerOptions": {
"paths": {
"@/*": ["./*"]
}
}
}Use "./src/*" if your app is in src/.
Run init
It finds app/globals.css and adds the theme to it, so keep that file imported in app/layout.tsx.
Add a component and use it
import { Button } from "@/components/ui/button";
export default function Home() {
return (
<div className="flex min-h-svh items-center justify-center">
<Button>Click me</Button>
</div>
);
}Server and Client Components
You can render every component from a Server Component, as the page above does. A component that needs the browser, for state, effects or a primitive's events, starts with "use client" itself, or imports a primitive that does: you don't add the directive to your page for it.
What you can't do from a Server Component is pass a function, such as onClick or onValueChange. Put the interactive part in a small file of your own that starts with "use client", and render that from the page:
"use client";
import { Button } from "@/components/ui/button";
export function SaveButton() {
return <Button onClick={() => console.log("saved")}>Save</Button>;
}Dark mode
The theme has a light and a dark set of variables; the dark one applies under a .dark class. The starter wires next-themes for you. In an existing app, install it and wrap <body>'s content in its provider with attribute="class":
bun add next-themesimport { ThemeProvider } from "next-themes";
import "./globals.css";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
{children}
</ThemeProvider>
</body>
</html>
);
}suppressHydrationWarning is there because the provider sets the class before React hydrates.
FAQ
Why do I get “Cannot find module '@/components/ui/button'”?
The @/* alias is missing or points at the wrong folder. Add "@/*": ["./*"] to compilerOptions.paths in tsconfig.json, or "./src/*" when the app is in src/, then restart the dev server.
The components render without styles. What's wrong?
Tailwind isn't building them, or the theme isn't loaded. Check that app/globals.css starts with @import "tailwindcss";, that init added the theme's variables to it, and that app/layout.tsx imports it. Tailwind CSS v3 can't build these components.
Does it work with the Pages Router?
Yes. init detects a Pages Router app and installs the same files; import the CSS from pages/_app.tsx. The examples on these pages use the App Router, which is what new apps get.
Do I need to add “use client” to my pages?
No. Components that need the browser carry it themselves. You need your own client file only to pass a function (an onClick, an onValueChange) to one of them from a Server Component.
My app is in a src folder. What changes?
The alias points at ./src/*, components land in src/components/ui, and the page you edit is src/app/page.tsx. create-next-app --src-dir sets this up, and init reads it from tsconfig.json.
How does the monorepo setup work?
init -t next --monorepo creates a workspace: the Next.js app in apps/web and the components in packages/ui. Add components from apps/web (or with -c apps/web) and they're written to the shared package, which the app imports as @workspace/ui/components/….
Does it work with Turbopack?
Yes. Next.js 16 builds with Turbopack by default, and the components are plain TypeScript and Tailwind classes, with nothing to configure in next.config.ts.
My app already uses shadcn/ui. Can I add shadcn.io components?
Yes. Run our init once so the theme and variants match, and answer no when it offers to reinstall your components. Adding one of ours with the same name as one of yours replaces that file, so commit first and review the diff.
Can I install the Radix UI versions instead of Base UI?
Yes: the same component under /r/radix/, such as https://www.shadcn.io/r/radix/dialog.json. Every component page has its command for each library; see Installation.