Next.js 15 EOL Is Oct 21, 2026: Upgrade Checklist for AI-Built Apps

Yatish Goel
Co-Founder & CTO

Next.js 15 reaches end of life on October 21, 2026. That is the date listed on endoflife.date, and it follows the two-year support window Vercel has applied since version 14. After it, the 15.x line gets no security patches. Next.js 16 has been out since October 22, 2025, and the current patch is 16.3.5 (September 11, 2026).
If your app was generated by Cursor, v0, Claude Code or Bolt in 2025, there is a good chance it is on Next.js 15, because that was the version those tools scaffolded for most of the year. This post covers what actually changes in 16, which of those changes hit AI-generated apps, and the order to do the work in so you are not debugging three problems at once.
What this post does not cover: the Pages Router. Everything below assumes the App Router, which is what every AI tool has generated since 2024.
Why the date matters more than usual
End of life is normally a slow-burn problem. For Next.js 15 it is sharper, for one reason: the May 2026 security release. HeroDevs' timeline notes that release patched 13 advisories in one go, covering middleware bypass, denial of service in Server Components and SSRF. Next.js 15 got those patches because it was still in maintenance.
After October 21 it will not get the next batch. An unpatched proxy or middleware bypass in an app whose entire auth check lives in middleware.ts (which describes most Cursor-built SaaS apps) is the kind of bug that turns into a data incident.
End of life (EOL), for a framework, is the date after which the maintainer ships no more fixes for that major version, including security fixes. The code keeps running; the safety net is gone.
What actually changes in Next.js 16
The full list is in the Next.js 16 announcement and the upgrade guide. Here is the subset that changes how an existing app builds or runs.
| Change | Next.js 15 | Next.js 16 | Who it hits |
|---|---|---|---|
| Default bundler | webpack (Turbopack opt-in) | Turbopack, stable, default for dev and build | Anyone with a custom webpack config |
| Request interception | middleware.ts, Edge runtime | proxy.ts, Node.js runtime | Every app with auth in middleware |
| Node.js minimum | 18 supported | 20.9 (18 dropped) | Apps deployed on older Docker images or VMs |
| TypeScript minimum | older versions allowed | 5.1 | Old lockfiles |
| params, searchParams, cookies(), headers() | Sync access still worked with a warning | Async only; the compatibility shim is removed | Most AI-generated code from early 2025 |
| next lint | Built in | Removed; use the ESLint CLI | CI pipelines |
| experimental_ppr route config | Supported | Removed; replaced by Cache Components | Apps that enabled PPR |
| React | 19.0 | 19.2 (View Transitions, useEffectEvent, Activity) | Mostly additive |
Two of these do almost all the damage in the apps we get sent.
1. Async request APIs, for real this time
Next.js 15 made params, searchParams, cookies(), headers() and draftMode() asynchronous, but it kept a compatibility path so old synchronous code still ran, with a console warning. AI tools generated a lot of that old synchronous code, because their training data was full of it.
Next.js 16 removes the compatibility path. Code like this fails:
export default function Page({ params }: { params: { id: string } }) {
const id = params.id // Next.js 16: params is a Promise, this is undefined
return <Dashboard id={id} />
}It needs to become:
export default async function Page({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params
return <Dashboard id={id} />
}There is a codemod for this (npx @next/codemod@canary next-async-request-api). It handles the obvious cases. It does not handle a cookies() call buried inside a helper that ten route handlers import, which is exactly how AI tools structure auth utilities.
2. middleware.ts becomes proxy.ts
The rename is mechanical: rename the file, rename the exported function to proxy. The upgrade codemod does it for you. The Next.js team's stated reason is to make the network boundary explicit.
The part that needs a human is the runtime change. proxy.ts runs on Node.js. middleware.ts ran on the Edge runtime. If your middleware did session checks against Supabase or Clerk, it will keep working, and it may get simpler now that Node APIs are available. If it relied on Edge-only behaviour, or if something in it assumed a very small bundle, test it in a preview deployment before production. We have written about the redirect loops that come out of this layer in Next.js proxy redirect loops behind a load balancer and the Clerk auth loop.
The upgrade, in order
Do these in sequence. Each step should end with a green build before you start the next one.
- Check the Node.js version everywhere it runs. Local, CI, Docker base image, Vercel project settings. Next.js 16 needs 20.9 or later. A Dockerfile pinned to
node:18-alpineis the single most common reason a first upgrade attempt fails before the code is even touched. - Commit, then run the upgrade codemod.
npx @next/codemod@canary upgrade latest. It updatesnext.config.jsfor Turbopack, migratesnext lintto the ESLint CLI, renames middleware to proxy, stripsunstable_prefixes and removesexperimental_ppr. - Run the async request API codemod.
npx @next/codemod@canary next-async-request-api. Then grep for anything it missed:grep -rn "cookies()\|headers()\|params\." app liband read each hit. - Build.
next buildnow uses Turbopack. If it fails with a message about a custom webpack config, decide:next build --webpackto keep webpack for now, or move the config to Turbopack options. Most generated apps have no custom config and pass here. - Remove `--turbopack` flags from your package.json scripts. They are redundant now and the upgrade guide recommends dropping them.
- Deploy to a preview and click through every authenticated route. Login, logout, a protected page while logged out, a server action, a webhook route. The proxy runtime change is invisible in a build and visible in production.
- Upgrade React types.
@types/reactand@types/react-domneed to match React 19.2, or you get type errors that look like Next.js problems and are not.
What to expect in time
For a typical AI-generated SaaS app (auth in middleware, a dozen routes, Supabase or Prisma, Stripe webhooks), the upgrade is two to three working days including testing. The codemods do the first hour of work; the remaining time is the buried cookies() calls and the proxy runtime check.
If the app is still on Next.js 14, it has been out of support since October 26, 2025. Go straight to 16; there is no benefit to stopping at 15 for a month.
What we did not test
We have not measured Turbopack build-time differences on the apps we upgrade, so we are not repeating Vercel's "2-5x faster builds" figure as our own. We also have not upgraded a Pages Router app to 16 this year; the checklist above is App Router only.
If your upgrade is stuck on a build error you cannot read, the Next.js development page explains how we take these on, and fix a vibe-coded app covers the wider audit when the framework version is only one of the problems.
Frequently asked questions
- Does my Next.js 15 app stop working on October 21, 2026?
- No. The app keeps running. What stops is support: no more security patches or bug fixes for the 15.x line. The risk is the next advisory, not the date itself. Next.js 15 received 13 patched advisories in May 2026, so a year without patches is not a safe place to sit.
- My app was built with Cursor or v0 and I do not know which Next.js version it uses. How do I check?
- Open package.json and look at the next entry, or run npx next --version in the project folder. Anything starting with 15 is affected. If you see 14, you are already out of support since October 26, 2025 and should upgrade to 16 directly rather than stopping at 15.
- Can I keep webpack instead of Turbopack in Next.js 16?
- Yes. If you have a custom webpack config, next build now fails on purpose rather than silently ignoring it. Run next build --webpack to keep webpack, or migrate the config to Turbopack options. Most AI-generated apps have no custom webpack config and can just take the default.
- Is renaming middleware.ts to proxy.ts really all it takes?
- For the file, yes: rename it and rename the exported function to proxy. The thing to check is the runtime. proxy.ts runs on Node.js, not the Edge runtime, so any code that relied on Edge-only behaviour or on being tiny needs a second look. Auth checks that call a database now work; ones that assumed Edge limits may behave differently.
Sources
#Next.js 16 #Next.js 15 EOL #upgrade #Turbopack #proxy.ts #vibe-coded apps #Cursor #v0

Yatish Goel
Co-Founder & CTO
Full-stack architect with US startup experience and an IIT Kanpur degree. Yatish drives the technical vision at HeyDev, designing robust architectures and leading development across web, mobile, and AI projects.


