---
name: building-nextjs-apps
description: Build Next.js 16 applications with correct patterns and distinctive design. Use when creating pages, layouts, dynamic routes, upgrading from Next.js 15, or implementing proxy.ts. Covers breaking changes (async params/searchParams, Turbopack, cacheComponents) and frontend aesthetics. NOT when building non-React or backend-only applications.
---
# Next.js 16 Applications
Build Next.js 16 applications correctly with distinctive design.
## Critical Breaking Changes (Next.js 16)
### 1. params and searchParams are Now Promises
**THIS IS THE MOST COMMON MISTAKE.**
```typescript
// WRONG - Next.js 15 pattern (WILL FAIL)
export default function Page({ params }: { params: { id: string } }) {
return
ID: {params.id}
}
// CORRECT - Next.js 16 pattern
export default async function Page({
params,
}: {
params: Promise<{ id: string }>
}) {
const { id } = await params
return ID: {id}
}
```
### 2. Client Components Need use() Hook
```typescript
"use client"
import { use } from "react"
export default function ClientPage({
params,
}: {
params: Promise<{ id: string }>
}) {
const { id } = use(params)
return ID: {id}
}
```
### 3. searchParams Also Async
```typescript
export default async function Page({
searchParams,
}: {
searchParams: Promise<{ page?: string }>
}) {
const { page } = await searchParams
return Page: {page ?? "1"}
}
```
---
## Core Patterns
### Project Setup
```bash
npx create-next-app@latest my-app --typescript --tailwind --eslint
cd my-app
# Add shadcn/ui
npx shadcn@latest init
npx shadcn@latest add button form dialog table sidebar
```
### App Router Layout
```typescript
// app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
{children}
)
}
```
### Dynamic Routes
```typescript
// app/tasks/[id]/page.tsx
export default async function TaskPage({
params,
}: {
params: Promise<{ id: string }>
}) {
const { id } = await params
const task = await getTask(id)
return (
{task.title}
)
}
```
### Server Actions
```typescript
// app/actions.ts
"use server"
import { revalidatePath } from "next/cache"
export async function createTask(formData: FormData) {
const title = formData.get("title") as string
await db.insert(tasks).values({ title })
revalidatePath("/tasks")
}
// Usage in component
```
### API Routes
```typescript
// app/api/tasks/route.ts
import { NextResponse } from "next/server"
export async function GET() {
const tasks = await db.select().from(tasksTable)
return NextResponse.json(tasks)
}
export async function POST(request: Request) {
const body = await request.json()
const task = await db.insert(tasksTable).values(body).returning()
return NextResponse.json(task, { status: 201 })
}
```
### Middleware → proxy.ts
```typescript
// proxy.ts (replaces middleware.ts in Next.js 16)
import { NextRequest } from "next/server"
export function proxy(request: NextRequest) {
// Authentication check
const token = request.cookies.get("token")
if (!token && request.nextUrl.pathname.startsWith("/dashboard")) {
return Response.redirect(new URL("/login", request.url))
}
}
export const config = {
matcher: ["/dashboard/:path*"],
}
```
---
## Data Fetching
### Server Component (Default)
```typescript
// This runs on the server - can use async/await directly
async function TaskList() {
const tasks = await fetch("https://api.example.com/tasks", {
cache: "no-store", // SSR, or
// next: { revalidate: 60 } // ISR
}).then(r => r.json())
return (
{tasks.map(task => - {task.title}
)}
)
}
```
### Client Component
```typescript
"use client"
import useSWR from "swr"
const fetcher = (url: string) => fetch(url).then(r => r.json())
export function ClientTaskList() {
const { data, error, isLoading } = useSWR("/api/tasks", fetcher)
if (isLoading) return Loading...
if (error) return Error loading tasks
return (
{data.map(task => - {task.title}
)}
)
}
```
---
## Project Structure
```
app/
├── layout.tsx # Root layout
├── page.tsx # Home page
├── globals.css # Global styles
├── api/ # API routes
│ └── tasks/route.ts
├── tasks/
│ ├── page.tsx # /tasks
│ └── [id]/page.tsx # /tasks/:id
├── actions.ts # Server actions
└── proxy.ts # Request proxy (middleware)
components/
├── ui/ # shadcn/ui components
└── task-list.tsx # App components
lib/
├── db.ts # Database connection
└── utils.ts # Utilities
```
---
## Next.js DevTools MCP
Use the next-devtools-mcp server for runtime diagnostics and development automation.
### Setup
```bash
claude mcp add next-devtools npx next-devtools-mcp@latest
```
Or in `settings.json`:
```json
{
"mcpServers": {
"next-devtools": {
"type": "stdio",
"command": "npx",
"args": ["next-devtools-mcp@latest"]
}
}
}
```
### Available Tools
| Tool | Purpose |
|------|---------|
| `init` | Establish context with available tools and best practices |
| `nextjs_docs` | Search and fetch official Next.js documentation |
| `browser_eval` | Automate browser testing with Playwright |
| `nextjs_index` | Discover running Next.js dev servers |
| `nextjs_call` | Execute MCP tools on running dev servers |
| `upgrade_nextjs_16` | Automated upgrade with codemods |
| `enable_cache_components` | Configure Cache Components for Next.js 16 |
### Key Use Cases
**1. Get Real-time Errors**
```
"What build errors are there in my Next.js app?"
"Show me TypeScript errors in the current project"
```
**2. Debug Runtime Issues**
```
"Check the dev server logs for errors"
"What runtime errors are happening on the dashboard page?"
```
**3. Upgrade Assistance**
```
"Upgrade this project to Next.js 16"
"Enable cache components for this app"
```
**4. Documentation Lookup**
```
"How do I use the Image component in Next.js 16?"
"What's the correct way to handle dynamic routes?"
```
### Next.js 16 MCP Endpoint
Next.js 16+ exposes a built-in MCP endpoint at `http://localhost:3000/_next/mcp` (or your dev server port). The devtools MCP automatically discovers and connects to running servers.
---
## Verification
Run: `python3 scripts/verify.py`
Expected: `✓ building-nextjs-apps skill ready`
## If Verification Fails
1. Check: references/ folder has nextjs-16-patterns.md
2. **Stop and report** if still failing
## Related Skills
- **styling-with-shadcn** - UI components for Next.js apps
- **fetching-library-docs** - Latest Next.js docs: `--library-id /vercel/next.js --topic routing`
- **configuring-better-auth** - OAuth/SSO for Next.js apps
## References
- [references/nextjs-16-patterns.md](references/nextjs-16-patterns.md) - Complete Next.js 16 patterns
- [references/frontend-design.md](references/frontend-design.md) - Aesthetic guidelines for distinctive UI
- [references/datetime-patterns.md](references/datetime-patterns.md) - UTC/timezone handling for datetime-local inputs