Next.js 15 reaches end of life on 21 October 2026, two days from now. Your site will not stop working on Wednesday. What stops is Vercel's promise of security patches for the 15.x line. If you are on the latest 15.5.x release, you have a few weeks to plan the move to Next.js 16. If you are on anything older, you are already exposed. Patch today.

Below: how the date is worked out, why the recent security record makes it matter more than usual, and how to run the upgrade without surprises.

What Next.js 15 end of life on 21 October 2026 actually means

The two-year rule and how the date is worked out

Next.js keeps each major version in Maintenance LTS for two years from its initial release. After that it is unsupported: no security patches, no bug fixes, no compatibility work. Next.js 15 shipped on 21 October 2024, so the two-year mark lands on 21 October 2026.

Two details catch people out. The clock runs from the major's original release date, not from the day it moved into Maintenance LTS. That is why Next.js 14 (released October 2023) ended on 26 October 2025, whatever was happening with 15. And the support policy page reportedly states the rule rather than printing an end date for 15. The 21 October date is the rule applied, and every tracker we checked agrees.

Next.js 16, released in October 2025, is the current Active LTS line. Its end of life is projected for October 2027. That is a projection, not an announced date, but plan around it. Whatever you upgrade to now will need the same conversation in about a year.

Why end of life does not mean it breaks on Wednesday

Your production build will behave identically on 22 October. Nothing is switched off. What changes is the promise. Vercel may still patch an unsupported version in rare cases, depending on severity, but the policy commits to nothing. Do not run production on the hope of a discretionary fix.

One more quirk: Maintenance LTS updates land as semver-minor releases, even when they contain breaking changes. If you have been taking 15.5.x updates without reading the notes, read them now.

Why the security record makes this more urgent than usual

July to October 2026: what shipped and how serious it was

In July 2026 Vercel moved from ad hoc patching to a pre-announced monthly security release schedule. The record since then, from the official Next.js security posts:

  • July: four high and five medium severity issues, fixed in 16.2.11 and 15.5.21.
  • August: the release was brought forward to 25 August to fix two critical vulnerabilities, in 16.3.3 and 15.5.24.
  • 22 September: an out-of-band update addressed an upstream issue, including Satori, that could lead to remote code execution. Next.js 15 was not affected, and 15.5.26 included only related hardening.
  • 30 September: one high, five medium and one low severity issue, fixed in 16.3.8 and 15.5.27.
  • 14 October: another out-of-band update shipped 16.4.1 and 15.5.28, covering two fixes postponed from September because of upstream dependency delays. One is a critical unauthenticated remote code execution flaw in the Image Optimization API when SVG files are used. Releasebot's changelog also lists a high-severity denial of service in App Router Server Actions fixed in 15.5.28.

That is at least one security release a month, with critical issues in two of the last three months. Releasebot also shows a 16.4.2 entry after 14 October, so check npm for the current patch before you pin anything.

Maintenance LTS ending matters more this year than in earlier years, because the patch rate is high and the issues are serious.

Why an unpatched framework is a real exposure

On most deployments Next.js is the web server. It parses incoming requests, runs middleware and handles auth redirects. A flaw in the framework is a flaw in the front door, not in some library deep in the stack. At the current cadence, a 15.x app left alone after 21 October will probably have a known, unfixed vulnerability within weeks.

Which situation are you in?

On the latest 15.5.x

On 15.5.28 or later, already awaiting your request APIs, with no custom webpack config? You are in the best position. Upgrade to 16 within the next few weeks. The window is short but defensible, and it closes with the first monthly security release that 15 does not get.

On an older 15.x minor

Pinned to an earlier minor such as 15.1 or 15.3? You are already behind. Every fix listed above shipped in a 15.5.x release. Bump to 15.5.28 today as a stopgap, confirm nothing regressed, then plan 16. Patching first means you are not migrating under pressure on an exposed codebase.

On Next.js 14 or earlier

You have been past end of life since October 2025. Do not go to 15 as an intermediate step: you would land on a version that is unsupported two days later. Go straight to 16 and treat it as a proper project. If the codebase came from another team and nobody is sure what is in it, start with the approach we describe in rescuing an inherited app with an audit first approach before touching versions.

What breaks moving from Next.js 15 to 16

The official upgrade guide on nextjs.org is the reference. These are the changes that will fail a build or a deploy.

Async request APIs, Turbopack and webpack config

Synchronous access to cookies, headers, draftMode, params and searchParams is fully removed. Version 15 only warned. If you deferred the work, it is now mandatory.

tsx
// Next.js 16: params is a Promise and must be awaitedimport { cookies } from 'next/headers'export default async function Page({  params,}: {  params: Promise<{ slug: string }>}) {  const { slug } = await params  const cookieStore = await cookies()  // ...}

Turbopack is now the default for both next dev and next build. If you have a custom webpack config, the production build fails rather than warns. next build --webpack opts out and buys time, but treat it as temporary. For older or heavily customised builds, this is the most likely real blocker. One third-party guide estimates weeks of migration for complex cases. That is opinion, not a rule, but it matches what we see when loaders and plugins have piled up over the years.

The proxy.ts rename and Node 20.9 minimums

middleware.ts becomes proxy.ts, and the exported function is renamed to proxy. Proxy runs on the Node.js runtime. The Edge runtime is not supported in proxy, so if you deliberately run middleware at the edge, work out what that means for latency and behaviour before you upgrade.

ts
// proxy.ts (previously middleware.ts)import { NextResponse } from 'next/server'import type { NextRequest } from 'next/server'export function proxy(request: NextRequest) {  if (!request.cookies.has('session')) {    return NextResponse.redirect(new URL('/login', request.url))  }  return NextResponse.next()}

The runtime minimums move too. Next.js 16 needs Node.js 20.9.0 (Node 18 is dropped), TypeScript 5.1.0 and React 19.2 in the App Router. Supported browsers are Chrome, Edge and Firefox 111+ and Safari 16.4+. The Node requirement is the one that bites, because it applies to your hosting, your CI images and every developer's machine, not just package.json.

Smaller breaks to sweep for: parallel route slots now need an explicit default.js, and AMP, serverRuntimeConfig, publicRuntimeConfig and the experimental ppr, dynamicIO and useCache flags are gone.

Get plain-English guides like this in your inbox.

One short email a month. WordPress, Shopify, SEO, no fluff. Unsubscribe in one click.

We never share your email.

The changes that will not fail your build

Most checklists stop at a passing build. These changes never fail it, which is why they cause trouble later.

Linting that silently stops

next lint is removed and next build no longer lints. If your CI relied on the build to catch lint errors, it now passes without checking anything. Call ESLint directly:

json
{  "scripts": {    "lint": "eslint .",    "build": "next build"  }}

Then make sure the pipeline runs npm run lint as its own step. We add this in the same pull request as the version bump so the gap never reaches the main branch.

Image defaults and caching behaviour

next/image defaults have changed. minimumCacheTTL is now four hours, the default qualities list is [75], the 16px entry is dropped from imageSizes, local IP addresses are blocked and a maximum of three redirects applies. next/legacy/image is removed and images.domains is deprecated in favour of remotePatterns. None of this fails a build, but it can change what users see, especially if you serve images from an internal host or depend on a specific quality setting.

Caching semantics shift too. revalidateTag(tag) is deprecated in favour of a two-argument form that takes a cacheLife profile, and updateTag() and refresh() are new. If your content updates depend on tag revalidation, as headless CMS setups usually do, test publish-to-live behaviour explicitly. This matters for teams weighing when headless WordPress with Next.js is worth it, because stale content after a publish is exactly the failure editors notice first.

Test what the build cannot

Before you ship, check image rendering on key templates, content freshness after a CMS publish, and that your CI actually runs ESLint. A green build proves none of these.

Running the upgrade as a project

Codemods, branch, preview and rollback

For most of the Next.js work we do as part of custom web app and SaaS development, the upgrade follows the same sequence.

  1. Patch first. Get onto the latest 15.5.x and deploy it. That separates "security fix" from "major upgrade", so if something breaks you know which change caused it.
  2. Branch and bump the runtime. Move CI, preview environments and local machines to Node 20.9 or later before touching Next.js.
  3. Run the codemods.
bash
npx @next/codemod@canary upgrade latestnpx @next/codemod@canary next-async-request-api .

The first handles most of the version bump. The second catches synchronous request API usage the main one misses. Next.js 16.1 also added a next upgrade command, and the official guide now describes an upgrade CLI that prepares migration guides and a codemod for an AI agent. It is new, so we review its output line by line rather than trusting it. 4. Decide on webpack. Either port your config to Turbopack or build with --webpack and log the port as a dated follow-up task. Do not let the flag become permanent by accident. 5. Rename middleware, fix lint and audit images. Do this in one pass, as covered above. 6. Preview against real traffic patterns. Deploy the branch to a preview URL and check auth flows, redirects, image-heavy pages and content revalidation. 7. Keep the rollback ready. Tag the last 15.5.x release so you can redeploy it in minutes if production misbehaves.

We scope this as a fixed piece of work with weekly delivery, so you watch the branch move through these steps each week rather than hearing about it at the end. If the move is part of a wider replatform, our guide to migrating from WordPress to Next.js without losing SEO covers the redirect and indexing side.

When buying time with extended support is defensible

There is an honest case for not upgrading this month. Picture a stable app, still on Node 18, with years of custom webpack plugins and Edge middleware the business depends on. Rushing that migration could do more harm than two quiet months on an unsupported version.

Third-party extended support exists for that situation. HeroDevs and TuxCare both publish on Next.js end of life and both sell patches for unsupported versions. Remember that the companies explaining why you need extended support are the companies selling it.

The trade-off is plain. You pay someone else to patch while your migration debt keeps growing, and Next.js 16 itself is projected to reach end of life in about a year. Extended support makes sense as a bridge with a fixed end date and a migration plan behind it. Without a plan, it only postpones the same decision at a higher cost.

Our recommendation: on the latest 15.5.x with a clean build, upgrade now. On an older minor, patch today and upgrade next. With a genuine blocker, buy time deliberately and use it to clear the blocker. To see what that looks like in practice, see our recent work, or send us your repository and we will reply within four hours during UK business hours.