React 19
React 19 (see the documentation for the version 19 here) is perhaps the most significant change this time around. This new version brings some changes that you might or might not heard about, including:
If you have a weird feeling you have seen some of these before, then that’s because you have, quite possibly in Next 14. This time around, Meta is bringing the support for these features to the wider audience, such as non Next.js users.
One underrated change is the full support for custom elements. React previously struggled with Web Components, but it’s all in the past now, as Meta’s JS library boasts full support.
React Compiler
Compiling framework/library code isn’t a new concept. Svelte, Vue, Solid, and others, have done it for a long time already. The React team caught wind of that some time ago, and first introduced the compiler during a React talk “React without memo” in 2021. About 3 years later, we can finally give the compiler a shot, and we can offload a lot of busy work that includes memoization. The ability to let the compiler perform optimizations will also mean our code should be simpler, while it could turn out that our apps will become faster. If you want to take a quick peek at the before and after code, you can jump in and have fun with the Compiler Playground.
React 19 Breaking Changes
For a full list of breaking changes, please refer to the blog post at 19.react.dev/blog.
Incremental Adoption of Partial Prerendering (Experimental)
Partial prerendering isn’t an entirely new feature - it was introduced in Next.js 14. The novelty here is the fact that now the feature can be adopted incrementally. This way, if you add “experimental_ppr” route config option to your page, you will opt the whole page into Partial Prerendering.
Why would you want to do it? Partial prerendering lets you combine static content with the dynamic one. Prerendering only a part of the page is a compromise between keeping data fresh as possible, and faster websites, reduced server load, and SEO.
“next/after” (Experimental)
The new module allows you to execute code after a response. Previously, if you deployed your site to a serverless hoster, running a function right after loading wasn’t as straightforward. Quoting the blog, “[d]eferring the work after responding to the user poses a challenge because serverless functions stop computation immediately after the response is closed.”
That’s why the Next.js team solved this issue by introducing “after()”. Why would you need it? It’s useful for “logging, analytics, and other external system synchronization”.
Caching Changes
Previously, Next.js App Router had highly opinionated caching defaults. Caching “fetch”, Client route changes, and GET route handlers requests was opt-out: they were all cached by default. Starting from this release, the caching behavior will be opt-in instead.
In other words, in fetch “no-store is used by default if a cache option is not provided. This means fetch requests will not be cached by default”. GET route handlers will not be cached unless you “opt into caching using a static route config option such as export dynamic = 'force-static'.” Lastly, to opt into router caching, set the route config option of “staleTime” to your preferred values for both dynamic and static pages.
For web app developers this means that you will have to consciously set cache times on your own, meaning you, in theory, get more control over caching.