Skip to content

Commit 7bbc9c2

Browse files
committed
upgrade 16 beta to stable
1 parent f9da965 commit 7bbc9c2

File tree

7 files changed

+216
-15
lines changed

7 files changed

+216
-15
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ startup_timeout_ms = 20_000
113113

114114
</details>
115115

116-
### Next.js Runtime Integration (Recommended for Next.js >= 16 beta)
116+
### Next.js Runtime Integration (Recommended for Next.js >= 16)
117117

118-
For Next.js 16 beta or later, enable the MCP server in your Next.js application to unlock powerful runtime diagnostics and integration with Claude Code:
118+
For Next.js 16 or later, enable the MCP server in your Next.js application to unlock powerful runtime diagnostics and integration with Claude Code:
119119

120120
**Update `next.config.ts` or `next.config.js`:**
121121

@@ -153,7 +153,7 @@ Help me upgrade my Next.js app to version 16
153153

154154
Your MCP client should provide guidance and tools for upgrading your Next.js application.
155155

156-
If you're on **Next.js 16 beta or later** with `experimental.mcpServer` enabled, you can also try:
156+
If you're on **Next.js 16 or later** with `experimental.mcpServer` enabled, you can also try:
157157

158158
```
159159
What's the structure of my Next.js routes?
@@ -194,7 +194,7 @@ Callable tools for automating Next.js development workflows:
194194

195195
### `upgrade_nextjs_16` Tool
196196

197-
Guides through upgrading Next.js to version 16 beta with automated codemod execution.
197+
Guides through upgrading Next.js to version 16 with automated codemod execution.
198198

199199
**Capabilities:**
200200
- Runs official Next.js codemod automatically (requires clean git state)

src/index.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ import {
2727
readFundamentalsSection,
2828
isNextjsFundamentalsUri,
2929
} from "./mcp-resources/nextjs-fundamentals-knowledge.js"
30+
import {
31+
getBetaToStableResource,
32+
readBetaToStableGuide,
33+
isBetaToStableUri,
34+
} from "./mcp-resources/nextjs-16-beta-to-stable.js"
3035

3136
async function main() {
3237
// Create MCP server instance
@@ -130,7 +135,8 @@ async function main() {
130135
server.setRequestHandler(ListResourcesRequestSchema, async () => {
131136
const nextjs16Resources = getNextjs16KnowledgeResources()
132137
const fundamentalsResources = getNextjsFundamentalsResources()
133-
const resources = [...nextjs16Resources, ...fundamentalsResources]
138+
const betaToStableResource = getBetaToStableResource()
139+
const resources = [...nextjs16Resources, ...fundamentalsResources, betaToStableResource]
134140

135141
return { resources }
136142
})
@@ -146,6 +152,8 @@ async function main() {
146152
content = readKnowledgeSection(uri)
147153
} else if (isNextjsFundamentalsUri(uri)) {
148154
content = readFundamentalsSection(uri)
155+
} else if (isBetaToStableUri(uri)) {
156+
content = readBetaToStableGuide()
149157
} else {
150158
throw new Error(`Unknown resource URI: ${uri}`)
151159
}

src/mcp-prompts/upgrade-nextjs-16-prompt.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ Run the official codemod to handle most changes automatically:
112112
# - Convert async params/searchParams automatically
113113
# - Update experimental config locations
114114
# - Fix other breaking changes
115-
<pkg-exec> @next/codemod@canary upgrade beta
115+
<pkg-exec> @next/codemod@canary upgrade latest
116116
```
117117

118118
**Note:** When prompted for options during codemod execution, select "yes" for all selections to apply all recommended changes.
@@ -147,7 +147,7 @@ If your project already uses `'use cache'` directives from Next.js 15 canary, yo
147147
<pkg-manager> add -D eslint-config-next@canary
148148
```
149149

150-
Otherwise, the beta version is recommended for most projects.
150+
Otherwise, the stable version is recommended for most projects.
151151
{{/IF_REQUIRES_CANARY}}
152152

153153
## PHASE 3: Analyze Remaining Issues
@@ -255,7 +255,15 @@ After the codemod runs, check for any remaining issues it might have missed:
255255
}
256256
```
257257

258-
**I. Edge Cases the Codemod May Miss**
258+
**I. Beta to Stable Migration (REQUIRED if upgrading from v16 beta)**
259+
260+
If you're upgrading from Next.js 16 **beta** to 16 **stable**, there are additional config migrations required:
261+
262+
{{BETA_TO_STABLE_GUIDE}}
263+
264+
**Key migration**: `experimental.cacheLife` must be moved to top-level `cacheLife`
265+
266+
**J. Edge Cases the Codemod May Miss**
259267
Review these manually:
260268

261269
- Complex async destructuring patterns
@@ -296,7 +304,7 @@ After the codemod runs, check for any remaining issues it might have missed:
296304
}
297305
```
298306

299-
**J. ViewTransition API Renamed (NOT handled by codemod)**
307+
**K. ViewTransition API Renamed (NOT handled by codemod)**
300308
Files: Search for imports of `unstable_ViewTransition` from React
301309
Action: Rename to `ViewTransition` (now stable in v16)
302310

@@ -305,7 +313,7 @@ After the codemod runs, check for any remaining issues it might have missed:
305313
+ import { ViewTransition } from 'react'
306314
```
307315

308-
**K. revalidateTag API Changes (Deprecation - NOT handled by codemod)**
316+
**L. revalidateTag API Changes (Deprecation - NOT handled by codemod)**
309317
Files: Search for `revalidateTag(` calls
310318
Check: All revalidateTag calls now require a profile parameter
311319

@@ -419,7 +427,7 @@ Report findings in this format:
419427
[ ] Git working directory is clean (no uncommitted changes)
420428
421429
## Phase 2: Codemod Execution
422-
- [ ] Ran codemod: `<pkg-exec> @next/codemod@canary upgrade beta`
430+
- [ ] Ran codemod: `<pkg-exec> @next/codemod@canary upgrade latest`
423431
- [ ] Selected "yes" for all codemod prompts
424432
- [ ] Codemod upgraded Next.js, React, and React DOM to latest
425433
- [ ] Codemod upgraded React type definitions to latest
@@ -439,6 +447,7 @@ Issues the codemod couldn't handle:
439447
[ ] next.config.js: turbopackPersistentCachingForDev → turbopackFileSystemCacheForDev
440448
[ ] next.config.js: Remove eslint config object
441449
[ ] next.config.js: Move serverComponentsExternalPackages out of experimental
450+
[ ] next.config.js: Move cacheLife out of experimental (beta → stable migration)
442451
[ ] revalidateTag API changes
443452
[ ] Edge cases in async APIs
444453
[ ] Deprecated features to update

src/mcp-prompts/upgrade-nextjs-16.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import type { GetPromptResult, Prompt } from "@modelcontextprotocol/sdk/types.js"
22
import { readFileSync } from "fs"
33
import { join } from "path"
4+
import { readBetaToStableGuide } from "../mcp-resources/nextjs-16-beta-to-stable.js"
45

56
export const upgradeNextjs16Prompt: Prompt = {
67
name: "upgrade-nextjs-16",
78
description:
8-
"Guide through upgrading Next.js to version 16 beta. CRITICAL: Runs the official codemod FIRST (requires clean git state) for automatic upgrades and fixes, then handles remaining issues manually. The codemod upgrades Next.js, React, and React DOM automatically. Covers async API changes, config moves, image defaults, parallel routes, and deprecations.",
9+
"Guide through upgrading Next.js to version 16. CRITICAL: Runs the official codemod FIRST (requires clean git state) for automatic upgrades and fixes, then handles remaining issues manually. The codemod upgrades Next.js, React, and React DOM automatically. Covers async API changes, config moves, image defaults, parallel routes, and deprecations.",
910
arguments: [
1011
{
1112
name: "project_path",
@@ -18,18 +19,22 @@ export const upgradeNextjs16Prompt: Prompt = {
1819
export function getUpgradeNextjs16Prompt(args?: Record<string, string>): GetPromptResult {
1920
const projectPath = args?.project_path || process.cwd()
2021

21-
// TEMPORARY: Set to false once Next.js 16 beta supports experimental.cacheComponents
22-
const REQUIRES_CANARY_FOR_CACHE_COMPONENTS = true
22+
// TEMPORARY: Set to false once Next.js 16 supports experimental.cacheComponents
23+
const REQUIRES_CANARY_FOR_CACHE_COMPONENTS = false
2324

2425
// Load critical rules (always embedded)
2526
const criticalRules = readFileSync(join(__dirname, "nextjs-16-critical-rules.md"), "utf-8")
2627

28+
// Load beta-to-stable migration guide (always embedded)
29+
const betaToStableGuide = readBetaToStableGuide()
30+
2731
// Load prompt template
2832
let promptTemplate = readFileSync(join(__dirname, "upgrade-nextjs-16-prompt.md"), "utf-8")
2933

3034
// Replace sentinel values
3135
promptTemplate = promptTemplate.replace(/{{PROJECT_PATH}}/g, projectPath)
3236
promptTemplate = promptTemplate.replace(/{{CRITICAL_RULES}}/g, criticalRules)
37+
promptTemplate = promptTemplate.replace(/{{BETA_TO_STABLE_GUIDE}}/g, betaToStableGuide)
3338

3439
// Handle conditional blocks
3540
if (REQUIRES_CANARY_FOR_CACHE_COMPONENTS) {
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# Next.js 16 Beta to Stable Migration Guide
2+
3+
## Overview
4+
5+
This guide covers the specific breaking changes when migrating from **Next.js 16.0.0-beta** to **Next.js 16.0.0 stable**.
6+
7+
If you're already on Next.js 16 beta and upgrading to stable, you need to apply these additional config migrations that were stabilized between beta and stable releases.
8+
9+
## Required Config Migrations
10+
11+
### 1. experimental.cacheLife → cacheLife
12+
13+
**Status**: BREAKING - Required for beta → stable migration
14+
15+
The `cacheLife` configuration has been moved out of the `experimental` object and is now a top-level config option.
16+
17+
**File**: `next.config.js` or `next.config.ts`
18+
19+
**Migration**:
20+
21+
```diff
22+
// next.config.js
23+
export default {
24+
- experimental: {
25+
- cacheLife: {
26+
- default: { stale: 3600, revalidate: 900, expire: 86400 },
27+
- custom: { stale: 1800, revalidate: 450, expire: 43200 },
28+
- },
29+
- },
30+
+ cacheLife: {
31+
+ default: { stale: 3600, revalidate: 900, expire: 86400 },
32+
+ custom: { stale: 1800, revalidate: 450, expire: 43200 },
33+
+ },
34+
}
35+
```
36+
37+
**Why this matters**:
38+
- Projects using Cache Components with custom `cacheLife` profiles will fail to recognize the config if it's still under `experimental`
39+
- The stable release expects `cacheLife` at the top level
40+
41+
**How to find**:
42+
```bash
43+
# Search for experimental.cacheLife in your config
44+
grep -r "experimental.*cacheLife" .
45+
# or
46+
rg "experimental.*cacheLife"
47+
```
48+
49+
### 2. experimental.cacheComponents remains experimental
50+
51+
**Status**: Still experimental in stable
52+
53+
The `experimental.cacheComponents` flag itself **remains experimental** and should stay under the `experimental` object.
54+
55+
```js
56+
// next.config.js
57+
export default {
58+
experimental: {
59+
cacheComponents: true, // ✅ Keep this in experimental
60+
},
61+
cacheLife: {
62+
// ✅ Move this to top-level
63+
default: { stale: 3600, revalidate: 900, expire: 86400 },
64+
},
65+
}
66+
```
67+
68+
## Detection Checklist
69+
70+
Run this checklist to verify your migration:
71+
72+
- [ ] Searched for `experimental.cacheLife` in `next.config.js`/`next.config.ts`
73+
- [ ] Moved `cacheLife` object to top-level if found
74+
- [ ] Verified `experimental.cacheComponents` remains in experimental (don't move this)
75+
- [ ] Tested dev server starts without config errors
76+
- [ ] Verified custom cacheLife profiles are recognized
77+
78+
## Complete Example
79+
80+
**Before (Next.js 16 beta)**:
81+
```js
82+
// next.config.js
83+
export default {
84+
experimental: {
85+
cacheComponents: true,
86+
cacheLife: {
87+
default: {
88+
stale: 3600,
89+
revalidate: 900,
90+
expire: 86400,
91+
},
92+
blog: {
93+
stale: 1800,
94+
revalidate: 600,
95+
expire: 43200,
96+
},
97+
},
98+
},
99+
}
100+
```
101+
102+
**After (Next.js 16 stable)**:
103+
```js
104+
// next.config.js
105+
export default {
106+
experimental: {
107+
cacheComponents: true, // Stays here
108+
},
109+
cacheLife: {
110+
// Moved to top-level
111+
default: {
112+
stale: 3600,
113+
revalidate: 900,
114+
expire: 86400,
115+
},
116+
blog: {
117+
stale: 1800,
118+
revalidate: 600,
119+
expire: 43200,
120+
},
121+
},
122+
}
123+
```
124+
125+
## Additional Notes
126+
127+
- This migration is **only required** if you're upgrading from Next.js 16 beta to stable
128+
- If you're upgrading from Next.js 15 or earlier directly to 16 stable, this doesn't apply (since you wouldn't have `experimental.cacheLife` yet)
129+
- The codemod `@next/codemod@canary upgrade latest` does NOT handle this migration automatically
130+
- Error you might see if not migrated: Custom cacheLife profiles not being applied, or config validation warnings
131+
132+
## Related Changes
133+
134+
For other Next.js 16 upgrade requirements, see:
135+
- `experimental.serverComponentsExternalPackages``serverComponentsExternalPackages` (top-level)
136+
- Async params/searchParams
137+
- Config location migrations
138+
- Image defaults changes
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import type { Resource } from "@modelcontextprotocol/sdk/types.js"
2+
import { readFileSync } from "node:fs"
3+
import { join } from "node:path"
4+
5+
/**
6+
* Next.js 16 Beta to Stable Migration Resource
7+
*
8+
* This resource provides specific guidance for upgrading from Next.js 16 beta
9+
* to Next.js 16 stable, covering config migrations and breaking changes that
10+
* happened between beta and stable releases.
11+
*/
12+
13+
const BETA_TO_STABLE_RESOURCE: Resource = {
14+
uri: "nextjs16://migration/beta-to-stable",
15+
name: "Next.js 16 Beta to Stable Migration",
16+
description:
17+
"Specific breaking changes and config migrations required when upgrading from Next.js 16 beta to stable (experimental.cacheLife → cacheLife, etc.)",
18+
mimeType: "text/markdown",
19+
}
20+
21+
/**
22+
* Get the beta-to-stable migration resource
23+
*/
24+
export function getBetaToStableResource(): Resource {
25+
return BETA_TO_STABLE_RESOURCE
26+
}
27+
28+
/**
29+
* Read the beta-to-stable migration guide content
30+
*/
31+
export function readBetaToStableGuide(): string {
32+
const filePath = join(__dirname, "nextjs-16-beta-to-stable.md")
33+
return readFileSync(filePath, "utf-8")
34+
}
35+
36+
/**
37+
* Check if a URI is the beta-to-stable migration resource
38+
*/
39+
export function isBetaToStableUri(uri: string): boolean {
40+
return uri === BETA_TO_STABLE_RESOURCE.uri
41+
}

src/mcp-tools/upgrade-nextjs-16.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const upgradeNextjs16InputSchema = z.object({
1616
})
1717

1818
export const upgradeNextjs16Tool = tool({
19-
description: `Guide through upgrading Next.js to version 16 beta.
19+
description: `Guide through upgrading Next.js to version 16.
2020
2121
CRITICAL: Runs the official codemod FIRST (requires clean git state) for automatic upgrades and fixes, then handles remaining issues manually. The codemod upgrades Next.js, React, and React DOM automatically.
2222

0 commit comments

Comments
 (0)