Two Next.js announcements landed within eight days of each other. Next.js 16.4 shipped on October 6 and recommends Cache Components for every app. On October 14, an out-of-band security update fixed two critical remote code execution issues and one high-severity denial of service.
If you run Next.js in production, those two events pull in different directions. One is urgent and small. The other is optional and large. The mistake we see teams make is bundling them into one upgrade, so a security patch waits on a migration that nobody has time for.
This post is a way to separate them.
Track 1: patch now
The October 14 release is available as v16.4.1 (Active LTS) and v15.5.28 (Maintenance LTS). Three issues are fixed:
| Issue | Severity | Who is affected |
|---|---|---|
Unauthenticated RCE in use cache functions that return multiple typed arrays |
Critical | App Router apps using Cache Components |
| Unauthenticated RCE in the Image Optimization API with SVG, via an upstream library | Critical | Next.js on glibc-based Linux |
| Denial of service through excessive CPU use | High | App Router apps with at least one Server Action |
Details are in the vendor advisory, including the GHSA identifiers, so we will not restate them here. Three points matter for planning.
First, for the use cache issue the advisory says there is no known workaround, and recommends upgrading immediately even if your app has no similar functions. Do not spend a day auditing whether you are exposed. Patch.
Second, the Image Optimization issue has a documented stopgap: make sure the sharp version Next.js uses is 0.35.5 or later. Upgrading Next.js to a patched version makes your package manager provide a fixed sharp automatically. If you cannot ship the full upgrade today, check your lockfile for sharp first.
Third, Pages Router apps and apps without Server Actions are not vulnerable to the denial of service. That tells you the blast radius, not whether to patch.
The commands from the advisory:
npm install next@15.5.28 # for 15.5
npm install next@16.4.1 # for 16.4
If you are on 16.0 to 16.3, the advisory only names 16.4.1 for the 16.x line. Treat the move to 16.4.1 as the patch, and read the 16.4 notes below before you merge it.
Keep the patch PR boring
A security patch should be a one-line diff plus a lockfile change. A reasonable checklist:
- Bump
next(andeslint-config-nextif you pin it) in its own pull request. - Run your existing build and end-to-end tests. Do not add feature flags or refactors in the same PR.
- Deploy to staging, hit an image route, a route with a Server Action, and your slowest page.
- Ship it, then watch error rates and p95 latency for a day.
If the jump from your current version to 16.4.1 is large, check the release posts for each minor version in between before you commit to "boring". Next.js 16.3, for example, introduced Instant Navigations, which changes prefetching behaviour. That is worth a staging pass even if your tests are green.
Track 2: decide on Cache Components
Next.js 16.4 says Cache Components will become the default in Next.js 17, and that new apps created with create-next-app now have it enabled. For existing apps it is a programming-model change: the 'use cache' directive and cacheLife replace the implicit caching behaviour of earlier App Router versions.
async function Projects({ userId }: { userId: string }) {
'use cache';
cacheLife('hours');
return renderProjects(await getProjects(userId));
}
Enabling it takes two config flags, cacheComponents and partialPrefetching. Turning on the flags is easy. The work is deciding, per component, what is cacheable and for how long.
Here is how we would decide whether to migrate now:
| Your situation | Suggested timing |
|---|---|
| Greenfield app | Start with Cache Components on |
| Mostly static marketing site or blog | Good candidate soon; ensureStatic helps guard it |
| Dashboard with per-user data and few perf complaints | Wait; schedule it before you move to Next.js 17 |
| Large app with weak test coverage | Fix the tests first, then migrate one route group at a time |
One more reason to separate the tracks. The most serious bug in the October 14 release sits in the Cache Components code path. That does not mean the feature is unsafe, and the fix is shipped. It does mean that newer, larger surface area deserves its own rollout, and your security patching should not depend on whether you have adopted it.
Useful additions in 16.4
Some of the 16.4 changes help whichever track you are on.
ensureStatic fails the build if dynamic content sneaks into a route that should be static. For ecommerce pages, marketing pages and blogs, it protects your hosting bill from an accidental request-time render:
// app/layout.tsx
export const ensureStatic = 'navigation';
The new navigation() API lets you keep part of a page out of a prefetch. If a list page prefetches every visible link, you can keep heavy detail, such as a whole message thread, until the user actually navigates.
next upgrade --agent prepares migration guides, codemods and verification steps for a coding agent. There is also experimental.agentUpgrade, which defaults to a 'security' policy that reminds you about upgrades addressing known vulnerabilities in your installed version. We think the reminder is worth having, but it is a nudge, not a deployment process. Someone still has to own the patch SLA.
Smaller things: Turbopack's disk cache uses 20 to 25 percent less space, production CSS Module class names are shorter, and React 19.3 ships with stable View Transitions. These are free wins and need no decisions.
A patch policy worth writing down
The practical lesson is organisational rather than technical. Before the next advisory, write down:
- Who is on call for framework security releases, and who approves a same-day deploy.
- A target time from advisory to production for critical issues (pick one that you can actually meet).
- That framework patches ship alone, never inside a feature branch.
- A way to see your running version in production, so you can answer "are we patched?" in a minute.
Takeaway
Patch to 16.4.1 or 15.5.28 this week, in a PR that contains nothing else. Then treat Cache Components as a planned migration with its own tests, owner and rollout, ahead of Next.js 17. If you want help with either, that is the kind of upgrade work we do for product teams.
