Next.js 16.3 is out, and the headline change is not a new API. It is that the App Router finally has a client-side cache.
Since Server Components landed, Next.js apps have been good at fetching data and rendering complete pages, and bad at feeling responsive. You click a link, the browser waits on the server, and the user stares at the old page until something arrives. The 'use cache' directive introduced in Next.js 16 solved the server half of that problem. Next.js 16.3 extends the same primitive to the client.
The release also ships a set of performance wins that apply to every existing app with no code changes: up to 90% less dev server memory, cached production builds, and 22% more requests handled under load.
Here is what actually changed in Next.js 16.3, what is opt-in, and whether you should upgrade.
What's new in Next.js 16.3 at a glance
Short answer: Next.js 16.3 is a minor release with two halves. The first half improves every existing app with zero code changes. The second half is Instant Navigations, an opt-in suite built on 'use cache' that brings client-side caching and SPA-style navigation to the App Router.
| Change | Availability | What you have to do |
Turbopack memory eviction in dev | Default | Nothing |
Turbopack FileSystem Cache for next build | Default | Nothing |
Native Node.js streams in App Router SSR | Default | Nothing |
Prefetch inlining | Default | Nothing |
Versioned docs for AI coding agents | Default | Run next dev |
TypeScript 7 type checking | Opt-in | Bump typescript to ^7 |
Root params, catchError, import.meta.glob | New APIs | Adopt where useful |
Instant Navigations | Opt-in | Two next.config.ts flags |
Rust React Compiler, network resilience | Experimental | Config flags |
Nothing here is a breaking change, which is why the Next.js team recommends every app upgrade.
Next.js 16.3 performance improvements you get on upgrade
These four changes require no application code changes at all. They are the reason to run npm install next@latest today even if you never touch Instant Navigations.
Up to 90% less dev server memory
Long next dev sessions used to balloon. Turbopack now combines disk caching for dev (shipped in 16.1) with memory eviction, and both are on by default in 16.3.
| App | Memory after compiling 50 routes (before) | After | Reduction |
vercel.com dashboard | 21.5 GB | 2 GB | ~90% |
nextjs.org | 4,600 MB | 840 MB | ~82% |
If you have been restarting your dev server every hour on a large app, this is the fix.
Faster builds with the Turbopack FileSystem Cache
The same disk cache now works with next build, so repeat builds read unchanged artifacts instead of recompiling them. Vercel has been running this in production for months.
| Project | Cold build | Cached build | Speedup |
nextjs.org | 21s | 9.2s | ~2.3x |
vercel.com/home | 66s | 46s | ~1.4x |
vercel.com/geist | 30s | 5.5s | ~5.5x |
The gain depends entirely on how much of your dependency graph is stable between builds. A CI runner that starts from a clean checkout every time gets nothing unless you persist the cache directory between runs.
Faster type checking with TypeScript 7
TypeScript 7, the native port of the compiler, is roughly 10x faster at type checking. next build can use it as soon as you bump the dependency:
pnpm add -D typescript@^7
This is opt-in and independent of everything else in the release, so it is the cheapest single win available.
Faster server-side rendering
The App Router rendering layer now uses native Node.js streams instead of web streams, removing the conversion overhead on every render. In Vercel's benchmarks, apps handle up to 22% more requests under load with no code changes. The implementation PR has the details.
For anyone running SSR on their own infrastructure, more requests per instance means fewer instances for the same traffic.
Client-side caching in the App Router with 'use cache'
This is the conceptual change worth understanding, because everything else in Instant Navigations builds on it.
Before Next.js 16, caching in the App Router was implicit. The framework guessed what to cache, and you spent your time discovering the guesses. 'use cache' inverted that: you mark what should be cached, and the rest is dynamic by default.
In 16.3, that directive now also caches on the client. Combined with Suspense, it means a route's UI can be split into three kinds of content:
- Prerenderable UI marked with
'use cache', which can be prefetched and shown instantly - Dynamic UI wrapped in
<Suspense>, which streams in at request time - Inline loading states that render immediately while dynamic content is in flight
Next.js can extract the first and third categories, ship them to the client before a navigation happens, and render them the moment a link is clicked. That is what makes a server-driven app feel like an SPA without giving up server rendering. If you are still deciding where each piece of your UI belongs, our breakdown of client vs server components in React is a useful companion.
Instant Navigations in Next.js 16.3
Instant Navigations is opt-in behind two flags:
// next.config.ts
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
cacheComponents: true,
partialPrefetching: true,
};
export default nextConfig;
The Next.js team has said these behaviors will become the default in a future major version, so adopting now is also a way to avoid a larger migration later.
Partial Prefetching
Prefetching used to be all or nothing. You either defined a reusable loading shell in loading.tsx or opted into aggressive full-page prefetching with <Link prefetch={true}>.
Partial Prefetching removes that choice. Next.js extracts a reusable loading shell from any route's UI, and each link decides how much of the target page to include. You get instant feedback on click without prefetching entire pages your users may never visit.
Instant Insights
The easiest way to ship a slow navigation was to forget a loading.tsx file. Instant Insights is a new DevTools panel that flags any navigation you hit in development that was not instant, and includes a prompt you can hand to a coding agent to apply the fix.
Better ISR for partially prerendered routes
If you prerender only some pages of a route with generateStaticParams, the remaining pages used to force a tradeoff: show a loading shell and never get prerendered, or block the first visitor entirely.
In 16.3 a non-prerendered page serves an instant loading shell on its first visit, upgrades to the fully prerendered page in the background, and serves cached content to everyone after that. This matters most for large catalogs and personalized dashboards where prerendering every path at build time is not realistic.
Navigation Inspector
Because prefetching is disabled in development, it is hard to see what a user actually sees mid-navigation. The Navigation Inspector pauses page loads and client-side navigations at the shell so you can inspect the exact loading state.
Playwright test helper
An instant navigation stays instant until someone adds a cookies() call to a shared header. The new instant() helper from @next/playwright lets you assert what must be visible before any network work completes, so the test fails when a refactor de-opts the route:
// e2e/instant-navigation.spec.ts
import { expect, test } from '@playwright/test';
import { instant } from '@next/playwright';
test('product title is available immediately', async ({ page }) => {
await page.goto('/products/shoes');
await instant(page, async () => {
await page.click('a[href="/products/hats"]');
await expect(page.locator('h1')).toContainText('Baseball Cap');
await expect(page.getByText('Checking inventory...')).toBeVisible();
});
await expect(page.getByText('12 in stock')).toBeVisible();
});
New Next.js 16.3 APIs worth adopting
Root params
Params defined above the root layout, like [lang], are effectively global, but the only way to read them was prop drilling. next/root-params exposes them directly to any Server Component:
// app/[lang]/posts/[slug]/page.tsx
import { lang } from 'next/root-params';
export default async function PostPage(
props: PageProps<'/[lang]/posts/[slug]'>,
) {
const { slug } = await props.params;
const language = await lang();
return (
<article>
<p>Language: {language}</p>
<p>Post: {slug}</p>
</article>
);
}
Root params also work inside use cache scopes, which makes internationalization considerably less painful. Support for route handlers and Server Actions is planned for a future release.
Custom error boundaries with catchError
React error boundaries in Next.js used to interfere with notFound and redirect, and could only reset client state. The new catchError export from next/error defines a boundary that leaves those functions alone and hands your fallback a retry() function that refetches the boundary's children, including any Server Components that failed to render.
That last part is the meaningful change. A failed data fetch on the server is now recoverable without a full page reload.
Glob imports in Turbopack
Turbopack now supports the Vite-compatible import.meta.glob API, so Server Components that read local files get hot module reloading:
const posts = import.meta.glob('./posts/*.md', { eager: true });
Anyone maintaining a file-based content directory has been writing fs.readdir wrappers for this.
Build fast, scale faster
Backend infrastructure and web hosting built for developers who ship.
Start for free
Open source
Support for over 13 SDKs
Managed cloud solution
Experimental features in Next.js 16.3
Two features are behind experimental flags and worth watching rather than shipping:
- Rust-based React Compiler (
experimental.turbopackRustReactCompiler) runs the compiler inside Turbopack instead of Babel. On large apps like v0, time fromnext devto a ready page dropped 34% on cold builds and 46% on warm ones. The Rust React Compiler currently targets projects that are not using Babel. - Network resilience (
experimental.useOffline) keeps navigations, fetches, and Server Actions pending instead of throwing when the connection drops, then retries on reconnect. AuseOfflinehook lets you surface that state to users.
Feedback goes in the Next.js 16.3 discussion.
Should you upgrade to Next.js 16.3?
Short answer: yes, upgrade now for the default improvements. Adopt Instant Navigations deliberately, one route at a time.
| Your situation | Recommendation |
On Next.js 16.x | Upgrade now. No breaking changes, immediate build and dev wins. |
Slow navigations are a known complaint | Enable both Instant Navigations flags and start with your highest-traffic route. |
Still on the Pages Router | Upgrade for the SSR and build gains. Instant Navigations is App Router only. |
Large generateStaticParams catalog | The new ISR behavior is the single biggest reason to adopt Cache Components. |
Heavy Babel usage | Skip the Rust React Compiler until you can drop Babel. |
For most projects, upgrading starts with:
npm install next@latest
Existing projects moving to Cache Components can follow the official migration guide, and the migration is designed to be run incrementally rather than in one pass.
Deploying Next.js 16.3 without rewriting your app for serverless
A Next.js minor release is only cheap to adopt if your host keeps up with it. This is where some teams run into friction: features like streaming SSR, Server Actions, and now client-side caching depend on the full Next.js server, and some hosting platforms rely on adapters to support newer Next.js capabilities.
Appwrite Sites runs Next.js in a container-based Node.js runtime rather than translating it into serverless functions, so SSR, API routes, middleware, and Server Actions work without the OpenNext adapter or platform-specific configuration. Upgrading to 16.3 is a dependency bump and a Git push.
To be fair about the tradeoff: Vercel ships Next.js features on day one because it builds the framework, and a container runtime has different cold start and scaling characteristics than edge functions. What you get in exchange is a deployment target where a Next.js upgrade does not turn into a hosting investigation, plus the rest of Appwrite's backend in the same project. If you are evaluating the move, the Vercel migration guide covers the specifics, and Next.js output modes explains why standalone builds are the better default for self-managed hosting.
Getting started with Next.js 16.3 on Appwrite Sites
Upgrade your next dependency, run your test suite, and deploy. If you want to try Instant Navigations without touching a production app, spin up a fresh Next.js project, enable cacheComponents and partialPrefetching, and deploy it to Appwrite Sites to see how the loading shells behave over a real network instead of localhost. The Next.js quick start gets you from create-next-app to a live URL in a few minutes, and Appwrite's free tier covers side projects.






