| name | nextjs-shadcn |
| argument-hint | [component or page] |
| description | Creates Next.js 16 frontends with shadcn/ui. Use when building React UIs, components, pages, or applications with shadcn, Tailwind, or modern frontend patterns. |
Next.js 16 + shadcn/ui
Build distinctive, production-grade interfaces that avoid generic "AI slop" aesthetics.
Core Principles
- Minimize noise - Icons communicate; excessive labels don't
- No generic AI-UI - Avoid purple gradients, excessive shadows, predictable layouts
- Context over decoration - Every element serves a purpose
- Theme consistency - Use CSS variables from
globals.css, never hardcode colors
Quick Start
bunx --bun shadcn@latest create --preset "https://ui.shadcn.com/init?base=radix&style=nova&baseColor=neutral&iconLibrary=lucide&font=geist-sans" --template next
Component Rules
Page Structure
export default function Page() {
return (
<>
<HeroSection />
<Features />
<Testimonials />
</>
);
}
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<>
<Header />
<main>{children}</main>
<Footer />
</>
);
}
Client Boundaries
"use client" only at leaf components (smallest boundary)
- Props must be serializable (data or Server Actions, no functions/classes)
- Pass server content via
children
Import Aliases
Always use @/ alias (e.g., @/lib/utils) instead of relative paths (../../lib/utils).
Style Merging
import { cn } from '@/lib/utils';
function Button({ className, ...props }) {
return <button className={cn('rounded px-4 py-2', className)} {...props} />;
}
File Organization
app/
├── (protected)/ # Auth required routes
│ ├── dashboard/
│ ├── settings/
│ ├── components/ # Route-specific components
│ └── lib/ # Route-specific utils/types
├── (public)/ # Public routes
│ ├── login/
│ └── register/
├── actions/ # Server Actions (global)
├── api/ # API routes
├── layout.tsx # Root layout
└── globals.css # Theme tokens
components/ # Shared components
├── ui/ # shadcn primitives
└── shared/ # Business components
hooks/ # Custom React hooks
lib/ # Shared utils
data/ # Database queries
ai/ # AI logic (tools, agents, prompts)
Next.js 16 Features
Async Params
export default async function Page({
params,
searchParams,
}: {
params: Promise<{ id: string }>;
searchParams: Promise<{ q?: string }>;
}) {
const { id } = await params;
const { q } = await searchParams;
}
Data Fetching vs Server Actions
CRITICAL RULE:
- Server Actions = ONLY for mutations (create, update, delete)
- Data fetching = In Server Components or
'use cache' functions
'use server';
export async function getUsers() {
return await db.users.findMany();
}
export async function getUsers() {
'use cache';
cacheTag('users');
cacheLife('hours');
return await db.users.findMany();
}
export default async function Page() {
const theme = (await cookies()).get('theme')?.value ?? 'light';
return <App theme={theme} />;
}
Caching
'use cache';
import { cacheTag, cacheLife } from 'next/cache';
export async function getProducts() {
cacheTag('products');
cacheLife('hours');
return await db.products.findMany();
}
Server Actions (Mutations Only)
'use server';
import { updateTag, revalidateTag } from 'next/cache';
import { z } from 'zod';
const schema = z.object({
title: z.string().min(1),
content: z.string(),
});
export async function createPost(formData: FormData) {
const parsed = schema.parse({
title: formData.get('title'),
content: formData.get('content'),
});
await db.insert(posts).values(parsed);
updateTag('posts');
}
Proxy API
Use proxy.ts for request interception (replaces middleware). Place at project root:
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function proxy(request: NextRequest) {
}
export const config = {
matcher: ['/dashboard/:path*'],
};
References
Package Manager
Always use bun, never npm or npx:
bun install (not npm install)
bun add (not npm install package)
bunx --bun (not npx)