Next.js 16.4 and React 19.3 across my side projects
Cache Components are the default in Next.js 16.4 and ViewTransition is stable in React 19.3, so I upgraded the apps I run at home.

All my side projects are Next.js on the front, most with a Go service behind, and they all run on the box at home. When a minor release lands I upgrade one, leave it a day, and then do the rest in a batch. Next.js 16.4 came out on 6 October, so this weekend was batch weekend.
The headline in 16.4 is that Cache Components are now the recommended way to build every app, and create-next-app switches them on by default. When Next 16 came out last year, cacheComponents: true was an opt-in. Existing apps don't get flipped for you, which I think is right, because it does change behaviour. With it on, everything is dynamic unless you mark it with "use cache", and the static parts of a page are prerendered as a shell while the dynamic parts stream in under <Suspense>. I'd moved most of my apps to it over the past year anyway, so this release mostly confirmed where things were heading.
There's also ensureStatic, which lets you say a route must stay static so the build fails if something dynamic sneaks in. I like the idea a lot for pages that are built from a data file, but check the release notes for exactly how to apply it, as I'm still getting used to it. Then there are new navigation and prefetch APIs, which I've read about and haven't used, so I won't try to explain them. And next upgrade --agent, which hands the upgrade to a coding agent along with the migration notes. I tried it on my smallest app, where there was almost nothing to change, so it bumped the packages, ran the build and stopped. Not much of a test. I'd want to see it on a messier upgrade, and I'd still read the diff. The rest of the release is performance: a smaller disk cache, lazy server HMR, a shared Turbopack runtime and smaller production bundles. I did notice the disk cache, since the box at home is never far from full.
React 19.3
React 19.3 came out on 9 September, bundled into 16.4. Two experimental features went stable, <ViewTransition> and Fragment refs, and there are no breaking changes, which is why it's 19.3 and not 20.
<ViewTransition> wraps the browser's View Transitions API in a component. React decides when a transition starts (a navigation, a startTransition, a Suspense reveal) and you say what should animate. On AI Radar I'd wanted the small cover image in the feed to grow into the big one on the issue page, so that's where I tried it:
// feed
import { ViewTransition } from "react";
<Link href={`/issue/${issue.id}`}>
<ViewTransition name={`cover-${issue.id}`}>
<img src={issue.cover} alt="" width={120} height={80} />
</ViewTransition>
<h2>{issue.title}</h2>
</Link>
// issue page
<ViewTransition name={`cover-${issue.id}`}>
<img src={issue.cover} alt="" width={960} height={640} />
</ViewTransition>
The same name on both sides and the browser morphs one into the other. Browsers without View Transitions just navigate normally. Names have to be unique on the page when the transition runs, and it's worth switching the animation off for people who've asked for reduced motion:
@media (prefers-reduced-motion: reduce) {
::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) {
animation: none !important;
}
}
Fragment refs let you put a ref on a <Fragment> and reach its DOM children without a wrapper div. I've only had one place where a wrapper would have broken a CSS grid, and I'd read the docs for the exact API rather than trust my memory of it.
The upgrade itself was the usual:
npm install next@16.4 react@19.3 react-dom@19.3 eslint-config-next@16.4
npm run build
Most apps built and passed their smoke tests first time. A couple needed small fixes, mainly a component reading cookies() without a Suspense boundary above it, which older versions had let me get away with, and an old experimental ViewTransition import. My deploys build on the Mac and ship only the standalone output, so a bad upgrade would have been one image to roll back. I didn't need to.
First published on my blog. Cover photo: Alexander Novikov, CC BY-SA 4.0, via Wikimedia Commons (source).
About the author
- Full stack engineer in London with 5+ years on production web platforms. I lead AI-assisted modernisation at Xanda: React and Go for the UK energy market, a government claims portal, and moving old Java and C++ systems onto the cloud. Outside work I run a small home server behind a Cloudflare Tunnel with a handful of public tools on it: Doorstep (rental alerts across Rightmove, OnTheMarket and OpenRent), SeenSooner (NHS A&E and planned-care waits), GridPulse (live GB grid carbon), Sift (LLM ticket triage that survives model failures) and AI Radar (a news digest written hourly by an n8n workflow). I write here about React and Next.js upgrades, Node, coding with AI agents, and the CVEs I've had to patch. Originals live at blogs.kishankanejiiya.tech.
Comments
Join the discussionNo comments yet. Be the first to comment.



