Next.js Skill
Use this skill to build, modify, review, migrate, and debug Next.js applications against the installed Next.js version and current official documentation. It is optimized for the App Router and Next.js 16+, but version-detects before applying version-sensitive guidance.
When to use
- Building or modifying a Next.js application (App Router preferred; Pages Router handled when present)
- Routing, layout, page, navigation, or route-handler work
- Server / Client Component decisions and boundary bugs
- Data fetching, streaming, Suspense, or mutation with Server Functions / Server Actions
- Cache / revalidation / ISR behavior, including Cache Components (
cacheComponents) - Route handlers, Proxy (formerly Middleware), metadata, images, fonts, CSS integration
- Turbopack, HMR, dev-server, build, and deployment failures
- Testing setup (unit, integration, E2E)
- Migration / upgrade work (especially to Next.js 16)
- Review of generated Next.js code for version-specific mistakes
Don't use for generic React, generic CSS, or Tailwind internals unless Next.js integration materially affects the answer. When Tailwind behavior is the question, defer to the installed Tailwind skill.
Authority order (highest first)
- Installed
nextpackage version in the target project - Observed runtime / build behavior (terminal, browser, Next.js MCP if available)
- Current official Next.js documentation for that installed version
- Current Next.js source / release information where necessary
- Bundled references in this skill
- Existing project code as evidence of current assumptions
- Remembered framework behavior (lowest — easily stale)
Do not infer current Next.js behavior from model memory when exact semantics matter. Inspect the installed next version and read the docs for that version before applying version-sensitive guidance. Prefer bundled node_modules/next/dist/docs/ when present, or fetch https://nextjs.org/docs with Accept: text/markdown. Do not blindly apply v16-only APIs to older projects.
Phase 1: Detect
Inspect before changing. Gather:
package.json—next,react,react-domversions; scripts; package manager- Lockfile —
package-lock.json,yarn.lock,pnpm-lock.yaml,bun.lock,bun.lockb - Installed versions:
npm ls next react react-dom(or pnpm/yarn/bun equivalent) next.config.*— router, output, turbopack, cacheComponents, serverActions, etc.app/vspages/vs mixed;src/folder if usedproxy.ts/middleware.ts/ route handlers / instrumentationtsconfig.json/jsconfig.json- CSS pipeline — global CSS, CSS Modules, Tailwind, PostCSS, Sass, CSS-in-JS
- Test setup — Jest / Vitest / Playwright / Cypress
- Deployment config / adapter hints / static export / Docker
- Current git status
Determine explicitly:
- Next.js version (major/minor/patch)
- App Router / Pages Router / mixed
- Package manager
- TypeScript or JavaScript
- Turbopack or Webpack build path
- Deployment target (Vercel, Node, Docker, static export, adapter)
- Whether
cacheComponents/ Cache Components is in use - Existing architecture and conventions
Completion criterion: you can state all of the above without guessing before making version-sensitive edits.
Phase 2: Classify
Classify the task and the failure before changing code.
Task type: new feature / modify existing / debug / migrate / review.
Failure category (when debugging):
- dev-server / runtime failure
- stale
.nextartifacts - HMR / Turbopack chunk mismatch
- browser cache / service-worker behavior
- missing static asset / font / image
- server/client boundary violation
- hydration mismatch
- routing / navigation problem
- caching / revalidation problem
- Server Action problem
- route-handler / API issue
- config mismatch
- build-time failure
- dependency / version mismatch
- deployment / runtime mismatch
- CSS pipeline issue
- external infrastructure issue
Do not "fix" a runtime failure by randomly changing framework configuration.
Phase 3: Root-cause-first debugging
For any failure:
- Inspect Phase 1 context.
- Reproduce through the original user-visible path (page load, navigation, build, test).
- Read the exact error, stack trace, and any linked
/docs/messages/URL. - Distinguish root cause from symptom using the failure categories above.
- For dev-only failures, verify against
next devand browser console / network. A passing production build does not prove a dev HMR bug is fixed. - For build failures, run
next buildcleanly and read the route table / prerender errors. Use--debug-prerenderwhen server source maps are needed. - For version-sensitive APIs, consult the docs for the installed version before deciding.
Phase 4: Smallest-fix rule
Inspect → reproduce → identify root cause → change the smallest coherent surface → run focused checks → verify through the original user-visible path.
Do not:
- rewrite working architecture
- add dependencies without a clear need
- convert Server Components to Client Components to silence errors
- disable framework checks merely to get a build
- clear caches as the final diagnosis without identifying why the failure occurred
- treat a successful component-level probe as an end-to-end fix
Phase 5: Server / Client boundary discipline
The App Router defaults to Server Components. Treat Client Components as an explicit opt-in.
- Server Components are the default for
page.tsx,layout.tsx, and most UI inapp/. - Add
"use client"only where a client boundary is actually required: state/event handlers, lifecycle logic, browser-only APIs, custom hooks that depend on them. - Keep client boundaries narrow. Interactive islands (
<Search />,<Modal />,<LikeButton />) should be Client Components; surrounding static UI stays server-rendered. - Pass data from Server Components to Client Components via serializable props. Functions (including event handlers) cannot cross as props.
- Use
children/ props to interleave Server Components inside Client Components without importing the Server Component into the client graph. - Browser-only APIs /
window/document/localStoragerequire a Client Component or a guarded hook. - Server-only secrets and data access must stay out of the client bundle. Use
server-onlypackage when necessary. - When a third-party component needs client features, wrap it in a thin Client Component rather than marking the whole page tree
"use client".
Phase 6: Data / caching discipline
Inspect the installed version and next.config.* before reasoning about caching.
Next.js 16+ with cacheComponents: true:
- Default is dynamic / uncached. Opt into caching explicitly with
"use cache". - Use
cacheLife()inside a cached scope to set lifetime. - Use
cacheTag()+revalidateTag()/updateTag()for on-demand invalidation. - Prefer tag-based revalidation over path-based.
updateTagis Server Actions only and immediately expires cache (read-your-own-writes).revalidateTagis stale-while-revalidate and works in Server Actions and Route Handlers.revalidatePathinvalidates by route path; use when tagging is overkill.refresh()refetches the current route's RSC Payload without invalidating tagged data.use cache: privateallows runtime APIs (cookies(),headers(),searchParams) but stores only in browser memory.use cache: remoteuses a remote cache handler; only worthwhile at high hit rates.fetchis not cached by default. Use"use cache"to opt in.
Without Cache Components (older projects):
- Caching uses
fetchoptions (cache,next.revalidate,next.tags),unstable_cache, and route segment configs (revalidate,dynamic, etc.). - Do not blindly apply
"use cache"/cacheLife/cacheTagto older projects. - When migrating, follow the Migrating to Cache Components guide.
Phase 7: Navigation / routing discipline
- File-system routing in
app/: folders are segments;page.tsx/route.tsmakes a segment public. - Layouts nest automatically and preserve state across navigations. Root layout must include
<html>and<body>. - Dynamic segments:
[slug],[...slug],[[...slug]];paramsis a promise — await it. - Route groups
(group)organize code without changing URLs; private folders_folderare not routable. - Parallel routes use
@slot; intercepting routes use(.),(..),(..)(..),(...). - Prefer
<Link>fromnext/linkover raw<a>for client-side transitions and prefetching. - Use
redirect()/permanentRedirect()fromnext/navigationfor server-side redirects; useuseRouter()for programmatic navigation in Client Components. - Use
notFound()+not-found.tsxfor 404 UI. - Route handlers (
route.ts) use Web Request/Response APIs;GETdefault is dynamic since v15. - Proxy (
proxy.ts) is the v16+ name for the formermiddleware.ts; use amatcherto avoid running on static assets.
Phase 8: Build / debug verification
Use the project's package manager and existing scripts. Typical checks may include:
npm run build
npm run lint
npm test
npx tsc --noEmit
but do not invent these commands if the project does not define them.
For dev-only failures, verify through next dev + browser console / network / Next.js MCP (get_errors, get_compilation_issues, compile_route).
For build failures, read the route table symbols:
○Static◐Partial Prerender●SSGƒDynamic
Use next build --debug-prerender for source-mapped prerender errors. Do not deploy --debug-prerender builds.
Phase 9: Migration / upgrade discipline
- Detect installed version first.
- For v16 upgrades, run the official codemod:
npx @next/codemod@latest upgrade latest. - Also run the async request API codemod if applicable:
npx @next/codemod@latest next-async-request-api . - Migrate
middleware.ts→proxy.tsvianpx @next/codemod@canary middleware-to-proxy . - Replace
experimental.turbopack/experimental.ppr/experimental.useCache/experimental.dynamicIOwith their v16 equivalents per the Version 16 upgrade guide. - Update
package.jsonscripts to remove--turbopack/--turbo; Turbopack is default in v16. - Keep Webpack only with explicit
--webpackflag if a custom webpack config is required. - After upgrade, verify
AGENTS.mdpoints tonode_modules/next/dist/docs/if available.
Phase 10: Documentation hygiene
When an implementation-sensitive detail matters:
- Prefer the bundled docs in
node_modules/next/dist/docs/(version-matched). - Otherwise fetch the official page with
Accept: text/markdownor append.mdto the nextjs.org/docs URL. - Record the source URL beside version-sensitive claims.
- If the Next.js MCP server (
next-devtools-mcp) is available, use it for runtime state before guessing. - Do not claim the bundled references in this skill are permanently exhaustive or current.
Critical anti-hallucination rules
- URLs are URLs, not local files. NPM package identifiers like
@next/bundle-analyzerornext/third-partiesare packages, not@file:references. - Never rewrite package identifiers into pseudo-file references.
- If documentation extraction returns no content, treat it as an extraction failure and retry via the official page or another supported retrieval path. Do not interpret "no content" as proof the feature does not exist.
- Preserve contradictions between sources until resolved by a higher authority.
- Never claim a single ingested page makes the skill "complete" or "exhaustive."
References
references/docs-index.md— navigation + source inventory + ownership mapreferences/app-router.md— App Router fundamentals and conventionsreferences/server-client-components.md— Server/Client Component rules, boundary, interleavingreferences/data-fetching-and-streaming.md— fetching, streaming, Suspense, React.cachereferences/mutations-and-server-actions.md— Server Functions, Server Actions, forms, securityreferences/caching-and-revalidation.md— Cache Components,use cache,cacheLife,cacheTag, revalidationreferences/routing-and-navigation.md— routing, layouts, Link, redirects, route handlers, Proxyreferences/error-handling.md— expected errors, error boundaries,catchError,notFoundreferences/configuration.md—next.config.*, Turbopack config, serverActions, cacheComponentsreferences/css-images-fonts-metadata.md— CSS, images, fonts, metadata, OG imagesreferences/turbopack-and-build.md— Turbopack, build output, prerender errors, bundle analysisreferences/debugging-and-development.md— dev server, HMR, debugging, MCP, local performancereferences/deployment-and-production.md— deploying, adapters, static export, Docker, self-hostingreferences/testing.md— Jest, Vitest, Playwright, Cypressreferences/migration-and-upgrades.md— v16 upgrade, codemods, Cache Components migrationreferences/source-manifest.md— source provenance and authority notes
Contributing to the skill
When ingesting a new Next.js documentation page:
- Read the page completely.
- Compare against existing references.
- Extract only claims supported by that page.
- Classify: operational rule →
SKILL.md; durable knowledge → canonical reference; navigation →docs-index.md; duplicate → no change. - Merge, don't append.
- Preserve contradictions and source URLs.
- Keep each concept owned by one reference file; cross-link duplicates.
- Report exactly what changed and why.