Tailwind v4 is dramatically faster (Rust-based engine) and simpler to configure than v3. Next.js 16 ships with first-class support and a one-step install.
1npm i -D tailwindcss@latest @tailwindcss/postcss1export default {
2 plugins: { "@tailwindcss/postcss": {} },
3};1@import "tailwindcss";
2
3@theme {
4 --color-brand: #f97316;
5 --font-sans: "Inter", ui-sans-serif;
6}That's the whole config. No tailwind.config.ts required — themes live in CSS.
1@layer utilities {
2 .text-balance { text-wrap: balance; }
3 .gradient-brand {
4 background: linear-gradient(135deg, theme(--color-brand) 0%, #ef4444 100%);
5 }
6}1npm i clsx tailwind-merge1// lib/cn.ts
2import { clsx, type ClassValue } from "clsx";
3import { twMerge } from "tailwind-merge";
4
5export function cn(...inputs: ClassValue[]) {
6 return twMerge(clsx(inputs));
7}1import { cn } from "@/lib/cn";
2
3<button className={cn(
4 "rounded-md px-4 py-2 text-sm font-medium",
5 variant === "primary" && "bg-brand text-white",
6 variant === "ghost" && "border bg-transparent",
7 disabled && "opacity-50 cursor-not-allowed",
8 className, // allow consumers to override
9)} />twMerge resolves conflicting utilities — e.g. px-2 px-4 becomes px-4. Always wrap consumer-overridable classes.
In v4, dark mode is a media query by default. To use a class:
1@import "tailwindcss";
2
3@variant dark (.dark &);Then toggle <html class="dark"> from a theme provider.
Tailwind classes are just strings — they cross the server/client boundary without any special handling. Server Components can use any Tailwind class.
1<div className="@container">
2 <article className="@md:grid @md:grid-cols-2 @md:gap-6">
3 {/* responds to its container's width, not viewport */}
4 </article>
5</div>1<div className="bg-blue-500/20 text-blue-700" /> // 20% opacity, no extra classes1<button className="transition-colors duration-200 hover:bg-brand active:scale-95" />For complex animations, reach for Framer Motion. For basic UI transitions, Tailwind alone is enough.