Setting Up Tailwind CSS v4 + shadcn/ui in Next.js from Scratch
(edited: March 29, 2026)
Uses pnpm or npm with TypeScript.
1. Create Project
Bash
npx create-next-app@latest my-project --typescript --eslint --app
cd my-project
When
create-next-appasks about Tailwind CSS, select No. We will set up v4 manually.
2. Install Packages
Tailwind CSS v4 (PostCSS Method)
Next.js uses the PostCSS plugin instead of the Vite plugin.
pnpm:
Bash
pnpm add tailwindcss @tailwindcss/postcss postcss
npm:
Bash
npm install tailwindcss @tailwindcss/postcss postcss
shadcn/ui Required Dependencies
pnpm:
Bash
pnpm add class-variance-authority clsx tailwind-merge lucide-react
npm:
Bash
npm install class-variance-authority clsx tailwind-merge lucide-react
Node.js Type Definitions
pnpm:
Bash
pnpm add -D @types/node
npm:
Bash
npm install -D @types/node
3. Create Files
postcss.config.mjs
Tauri uses the Vite plugin (@tailwindcss/vite), but Next.js uses the PostCSS plugin.
JAVASCRIPT
const config = {
plugins: {
"@tailwindcss/postcss": {},
},
};
export default config;
src/app/globals.css
Based on the Next.js App Router, write this in src/app/globals.css.
CSS
@import "tailwindcss";
:root {
--background: oklch(1 0 0);
--foreground: oklch(0.1450 0 0);
/* ... other CSS variables */
}
.dark {
--background: oklch(0.1450 0 0);
--foreground: oklch(0.9850 0 0);
/* ... dark mode variables */
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
/* ... theme variable mappings */
}
src/lib/utils.ts
TYPESCRIPT
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
components.json
Differences from the Tauri setup: rsc is true, and the CSS path is src/app/globals.css.
JSON
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/app/globals.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
4. Modify Files
tsconfig.json
JSON
{
"compilerOptions": {
// ... existing settings
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
If created with
create-next-app, the@/*alias may already be configured.
src/app/layout.tsx
TYPESCRIPT
import type { Metadata } from "next";
import "./globals.css";
export const metadata: Metadata = {
title: "My App",
description: "Next.js + Tailwind CSS v4 + shadcn/ui",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
src/app/page.tsx
TYPESCRIPT
export default function Home() {
return (
<div className="flex items-center justify-center min-h-screen">
<h1 className="text-4xl font-bold">Hello, Next.js + Tailwind v4</h1>
</div>
);
}
5. Adding shadcn/ui Components
Bash
npx shadcn@latest add button
npx shadcn@latest add card
# Add any components you need...
Or initialize everything at once with shadcn init:
Bash
npx shadcn@latest init
Components are automatically generated in the src/components/ui/ folder.
6. Differences from Tauri Setup
| Item | Tauri (Vite) | Next.js |
|---|---|---|
| Tailwind Integration | @tailwindcss/vite (Vite plugin) | @tailwindcss/postcss (PostCSS plugin) |
| Config File | Add plugin in vite.config.ts | Create separate postcss.config.mjs |
| CSS File Location | src/index.css | src/app/globals.css |
| Entry Point | Import CSS in src/main.tsx | Import CSS in src/app/layout.tsx |
| RSC Support | false (client-only) | true (React Server Components) |
tailwind.config.js | Not required (v4) | Not required (v4) |
7. Key Features
- Tailwind CSS v4: CSS-first configuration, no
tailwind.config.jsneeded - PostCSS Integration: Seamlessly integrates with Next.js build pipeline
- Path Alias: Use
@/*as shorthand forsrc/*paths - Theme System: CSS variable-based, light/dark mode support via
@theme inline - shadcn/ui: RSC compatible, component library ready to use
- App Router: Based on Next.js 15 App Router architecture