Next.js 16.3 Preview improves navigation, build performance, server rendering,
and AI-assisted development. It is available through the preview npm
dist-tag for early testing.
This unlisted post is a reference for the features and behavior included in the preview. Preview releases may change before the stable release. Test against your application and report issues through GitHub Issues.
- Instant Navigations: Partial Prefetching, App Shells, Instant Insights, the Navigation Inspector, and navigation testing
- Improvements to Cache Components:
Upgrading Fallback Shells, typed root parameters, and
io() - Turbopack: Build caching by default, memory eviction,
import.meta.glob, and compatibility improvements - AI Workflows: Version-matched documentation, automatic project instructions, compilation tools, and Skills
- Rendering and Runtime: Native Node.js streams and stable error recovery APIs
- Deprecations: Edge Runtime and
preferredRegion - Developer Tools: Server HMR for route and metadata handlers, prerender source maps, client instrumentation, and TypeScript 6 compatibility
Install the Preview
Upgrade an existing application:
npm install next@preview react@latest react-dom@latestUse the same package manager and React versions already used by the application when appropriate.
Instant Navigations
Navigation performance has three parts: how quickly the interface responds, how quickly content loads, and how well the experience holds up on a slow or unreliable connection. Improving one has historically meant compromising another.
Partial Prefetching combines server rendering, streaming, and client caching. Next.js prepares a reusable App Shell before navigation, renders it immediately from the client cache, then streams the remaining content from the server.
Partial Prefetching
Partial Prefetching changes the default unit of prefetching from a complete page to its reusable App Shell. The shell can include shared layouts, cached content, static UI, and Suspense fallbacks. Dynamic data is fetched when the user navigates (#94448, #94510).
This preview is best suited to primarily dynamic applications. Static-heavy applications may regress from current prefetching behavior until additional optimizations are ready. Partial Prefetching will become the default after these workloads are well supported.
To enable Partial Prefetching across the application, enable Cache Components
and partialPrefetching:
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
cacheComponents: true,
partialPrefetching: true,
};
export default nextConfig;With Partial Prefetching enabled:
- A default
<Link>prepares the reusable App Shell. <Link prefetch={true}>opts into prefetching page-specific cacheable content. Dynamic data is fetched during navigation.- One App Shell can be reused for different values of the same dynamic route.
- Fully static routes use the same App Shell navigation model as dynamic routes.
The App Shell is downloaded once per filesystem route, rather than once per link. This keeps the default prefetch cost bounded while allowing every URL that shares the route to render an immediate UI.
Define the App Shell using existing React and Next.js APIs. Client Components
and loading.tsx can render in the shell. For more control, place
URL-dependent or dynamic work behind <Suspense>; the surrounding UI and
fallback become reusable shell content.
For incremental adoption, enable Cache Components without
partialPrefetching, then opt in one route at a time:
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
cacheComponents: true,
};
export default nextConfig;export const prefetch = 'partial';Because the App Shell is rendered on the server, it can include personalized, session-specific data such as cookies, then cache that result on the client.
Learn more in the Instant Navigation guide
and prefetch reference.
App Shells Across Rendering Paths
Next.js can extract an App Shell from one page's prefetch and reuse it for links to other pages in the same route, even if they have not been prerendered or fully prefetched. These navigations can show instant UI while Next.js requests and renders the destination on the server (#93801, #94442).
Instant Validation and Insights
With Cache Components enabled, Next.js validates navigations during development and reports work that prevents the App Shell from rendering immediately (#94312). Instant Insights cover cases including:
- Uncached data outside a local Suspense boundary
- Synchronous I/O during prerendering
- Dynamic metadata or viewport generation
- Missing fallbacks in parallel routes
To opt out of automatic validation and validate only routes that explicitly
export instant, set validationLevel to 'manual-warning':
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
experimental: {
instantInsights: {
validationLevel: 'manual-warning',
},
},
};
export default nextConfig;The route-level
instant
export is stable in Next.js 16.3
(#94578). Use it to validate
that navigations into a page or layout produce an immediate UI:
export const instant = true;Development validation is stable. Experimental validation modes that run
during next build remain experimental.
Navigation Inspector
The Navigation Inspector in the Next.js DevTools freezes a destination after its prefetched UI renders and before the remaining dynamic content streams in (#94027).
Run next dev, open Next.js DevTools, select Navigation Inspector, then
choose Start Capturing. Refresh the page or select a link to freeze the
initial or prefetched UI.
Use it to inspect:
- The destination layout
- Cached content available at navigation time
- Suspense fallbacks and loading states
- Boundary placement in the route tree
Select Continue Rendering to let the navigation finish.
Navigation Testing
The instant() helper in @next/playwright lets Playwright tests
assert on the UI available before dynamic content streams in:
The helper is designed for Playwright and uses a cookie-based protocol to hold back dynamic content during the callback.
npm install --save-dev @next/playwright@preview @playwright/testimport { 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();
});Inside the callback, only the instant shell is visible. After the callback returns, dynamic content continues rendering.
Improvements to Cache Components
Enable Cache Components:
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
cacheComponents: true,
};
export default nextConfig;The model remains:
- Block: Await work required before rendering.
- Cache: Add
'use cache'when work can be reused. - Stream: Place dynamic work behind
<Suspense>.
Upgrading Fallback Shells
With Incremental Static Regeneration for Cache Components, Next.js can upgrade a fallback shell for a parameter not known during the build. The first request receives the fallback immediately while Next.js generates the maximally static route shell for later requests. Parameters that cannot be prerendered remain dynamic (#89063).
Typed Root Parameters
next/root-params
provides typed accessors for dynamic parameters above the root layout:
import { lang } from 'next/root-params';
export default async function RootLayout({ children }: LayoutProps<'/[lang]'>) {
return (
<html lang={await lang()}>
<body>{children}</body>
</html>
);
}These accessors can also be used in shared server utilities.
Root parameter accessors are generated during development and builds, and are enabled by default (#91019, #93863). They are limited to Server Components and server utilities, and are not available in Client Components, Server Actions, or Route Handlers.
io()
io()
marks an I/O boundary. Place it before synchronous I/O such as new Date() to
prevent deoptimizations during prerendering:
import { io } from 'next/cache';
export default async function TimePage() {
await io();
const generatedAt = new Date().toISOString();
return <p>Generated at: {generatedAt}</p>;
}It can also precede native I/O that Next.js does not instrument, such as a database query, to avoid running work whose result would be discarded, for example, during static prerendering:
import { io } from 'next/cache';
import { db } from '@/lib/db';
export default async function OrdersPage() {
await io();
const orders = await db.query('SELECT * FROM orders LIMIT 10');
return <OrdersList orders={orders} />;
}Like connection(), io() suspends during static prerendering. Unlike
connection(), it does not imply that the work requires a request or user
navigation. This allows io() inside 'use cache' scopes, where the I/O result
can be computed and cached ahead of navigation. connection() cannot be
cached because it specifically waits for request-time rendering.
io() is stable in Next.js 16.3
(#93621).
Turbopack
Build Caching
Turbopack filesystem caching
is enabled by default for production builds in Next.js 16.3 Preview. Turbopack
saves and restores compiler data in the .next directory, reducing repeated
work across next build commands.
No configuration changes are required. To temporarily disable build caching while investigating build behavior:
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
experimental: {
turbopackFileSystemCacheForBuild: false,
},
};
export default nextConfig;Delete the .next directory when measuring a cold build. Preserve it between
builds when measuring or using the warm build path.
Ephemeral CI environments must restore and save .next between builds to
benefit from the cache. Without a persisted .next directory, every build
starts cold.
Development Memory Eviction
Development memory eviction allows Turbopack to move inactive compiler data from memory to disk and restore it when needed, reducing memory usage during long development sessions.
Memory eviction is enabled by default when the development filesystem cache is active, so no action is required (#94452, #94439).
Disable it temporarily when investigating cache or development performance:
const nextConfig = {
experimental: {
turbopackMemoryEviction: false,
},
};
export default nextConfig;import.meta.glob
Turbopack supports the Vite-compatible
import.meta.glob API:
const posts = import.meta.glob('./posts/*.mdx');By default, each value is a function that loads the matching module. Use
eager: true to import every match immediately:
const posts = import.meta.glob('./posts/*.mdx', {
eager: true,
});The API supports named imports, multiple and negative patterns, query strings
such as ?raw and ?url, custom base paths, and generated TypeScript types
(#92640).
This API is available with Turbopack and is not supported by the webpack bundler in Next.js.
Other Turbopack Updates
The preview also includes smaller output and compatibility improvements. See the Turbopack documentation for the complete configuration reference.
- Local PostCSS configuration: The experimental
turbopackLocalPostcssConfigoption resolves the configuration closest to each CSS file, supporting monorepos with different transforms (#91338). - Smaller output: Applications no longer include unused support for top-level async (#94376), Workers (#94372), or WebAssembly (#94373).
- Improved tree shaking: More unused CommonJS and local assignments can be removed (#94293, #94294).
- Node.js compatibility: Improved support for
import.meta.url,createRequire(), andworker_threads, including on Windows (#94179, #92153, #93432). - Package compatibility: Improved support for package export conditions and subpath imports (#93970, #93308).
- Development reliability: Loader crashes now produce actionable errors, and CSS HMR works correctly in Safari (#93926, #92123).
AI Workflows
Version-Matched Documentation
Next.js ships version-matched framework documentation inside the installed package (#89850):
01-app/
02-pages/
03-architecture/
index.mdxThe documentation matches the installed version. New projects created with
Create Next App include AGENTS.md and CLAUDE.md instructions that direct
coding agents to these local docs.
Automatic Setup for Existing Applications
When next dev detects a supported coding-agent environment and no managed
Next.js instruction block is present, it
creates or updates the appropriate file (#92910).
Check AGENTS.md for the block between <!-- BEGIN:nextjs-agent-rules --> and
<!-- END:nextjs-agent-rules -->. Content outside the managed block is
preserved. If automatic detection does not run, generate the files manually:
npx @next/codemod@canary agents-mdDisable automatic generation when needed:
const nextConfig = {
agentRules: false,
};
export default nextConfig;Compilation Tools
The Next.js MCP server exposes routes, errors, logs, page metadata, and Server Action information. Next.js 16.3 adds two Turbopack-powered tools:
get_compilation_issuesreturns compilation warnings and errors for the whole project without requiring an open browser page (#92062).compile_routecompiles a specific route on demand and returns its compilation issues without issuing an HTTP request (#93337).
Add next-devtools-mcp to the project's MCP configuration:
{
"mcpServers": {
"next-devtools": {
"command": "npx",
"args": ["-y", "next-devtools-mcp@latest"]
}
}
}Start next dev. The MCP client discovers the running development server.
Next.js Skills
The Next.js repository includes first-party agent Skills:
next-dev-loopverifies changes through the development MCP server and a real browser (#93943).next-cache-components-optimizerimproves and verifies the static shell for initial loads and client navigations (#94035).
List or install them with the open skills CLI:
npx skills add vercel/next.js --list
npx skills add vercel/next.js \
--skill next-dev-loop \
--skill next-cache-components-optimizerRendering and Runtime
Native Node.js Streams
The Node.js App Router rendering path now uses native Node.js streams by default (#90500, #94311), reducing conversion overhead while rendering responses.
No application changes or configuration are required. Routes using the Node.js runtime use this path automatically.
On the force-dynamic bench/basic-app production fixture:
| Metric | Web Streams | Node.js streams | Change |
|---|---|---|---|
| Average latency | 44.5ms | 29.5ms | 33.7% lower |
| Throughput | 1,064 req/s | 1,599 req/s | 50.3% higher |
This is a targeted synthetic workload, not a universal expectation.
Stable Error Recovery APIs
The error recovery APIs introduced experimentally in Next.js 16.2 are stable
in 16.3. The unstable_ prefixes have been removed:
unstable_retry()is nowretry().unstable_catchError()is nowcatchError().
App Router error components receive retry() for recovery from errors that
require fresh Server Component data. Error components are Client Components.
Unlike reset(), which only clears the boundary's local error state, retry()
refreshes and re-renders the boundary's children inside a React Transition:
'use client';
export default function Error({
error,
retry,
}: {
error: Error & { digest?: string };
retry: () => void;
}) {
return (
<div>
<p>{error.message}</p>
<button onClick={() => retry()}>Try again</button>
</div>
);
}For component-level recovery, catchError() creates a reusable Client
Component error boundary without requiring an error.tsx route file:
'use client';
import { catchError, type ErrorInfo } from 'next/error';
function ErrorFallback(props: { title: string }, { error, retry }: ErrorInfo) {
const message = error instanceof Error ? error.message : 'Unknown error';
return (
<div>
<h2>{props.title}</h2>
<p>{message}</p>
<button onClick={() => retry()}>Try again</button>
</div>
);
}
export const ErrorBoundary = catchError(ErrorFallback);Use the returned component to wrap the UI that should recover independently:
import { ErrorBoundary } from '../error-boundary';
export default function DashboardPage() {
return (
<ErrorBoundary title="Dashboard error">
<Dashboard />
</ErrorBoundary>
);
}The generated boundary preserves Client Component state outside the boundary,
does not intercept framework control-flow errors such as redirect() and
notFound(), and clears its error state after navigation to a different route.
Deprecations
Edge Runtime and preferredRegion
The Edge Runtime and the preferredRegion route segment config are deprecated
in Next.js 16.3. Builds now warn when an application uses either API
(#93369).
New routes should use the default Node.js runtime. Existing applications should
remove export const runtime = 'edge' and export const preferredRegion from
route files. See the
Edge Runtime
and
preferredRegion
deprecation guides for migration details.
Developer Tools
Server HMR for Route and Metadata Handlers
Server HMR preserves unchanged server modules when application code changes.
- App Route Handlers now preserve unchanged modules during Fast Refresh (#91466).
- Metadata routes such as
manifest.ts,robots.ts, andsitemap.tsparticipate in Server HMR (#93110).
Server HMR remains a Turbopack development feature.
Prerender Source Maps
Prerender source maps
are enabled by default while generating static pages during next build
(#93280). Prerender failures
point back to application source.
Source maps consume memory. Disable them when investigating build memory:
const nextConfig = {
enablePrerenderSourceMaps: false,
};
export default nextConfig;Other Developer Updates
- Client instrumentation for integrations:
instrumentationClientInjectlets config wrappers inject setup before hydration without editing the application'sinstrumentation-client.tsfile (#93785). Application developers should continue usinginstrumentation-client.tsdirectly. - TypeScript 6 compatibility: Next.js, Create Next App, codemods, and the TypeScript integration support the TypeScript 6 toolchain (#91257).
- More reliable development sessions: HMR reconnects after a computer sleeps and wakes, and the development status indicator no longer flickers during bursts of updates (#91416, #93229).
--debug-build-pathswithsrc: Build path filtering now works whenapporpagesis inside thesrcdirectory (#94016).
Included Patch Fixes
The preview includes the fixes from Next.js 16.2.7, including its prior security and bug-fix rollups.
Feedback and Community
This is a preview release. Share feedback and help shape Next.js 16.3:
For regressions and compatibility issues, include a minimal reproduction and
confirm the behavior against next@preview.