Skip to content
Back to Blog

Tuesday, June 9th 2026

Next.js 16.3 Preview: Reference Changelog

Posted by

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:

terminal
npm install next@preview react@latest react-dom@latest

Use 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:

next.config.ts
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:

next.config.ts
import type { NextConfig } from 'next';
 
const nextConfig: NextConfig = {
  cacheComponents: true,
};
 
export default nextConfig;
app/products/[id]/page.tsx
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':

next.config.ts
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:

app/products/[id]/page.tsx
export const instant = true;

Development validation is stable. Experimental validation modes that run during next build remain experimental.

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.

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.

terminal
npm install --save-dev @next/playwright@preview @playwright/test
e2e/navigation.test.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();
});

Inside the callback, only the instant shell is visible. After the callback returns, dynamic content continues rendering.

Improvements to Cache Components

Enable Cache Components:

next.config.ts
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:

app/[lang]/layout.tsx
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:

app/time/page.tsx
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:

app/orders/page.tsx
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:

next.config.ts
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:

next.config.ts
const nextConfig = {
  experimental: {
    turbopackMemoryEviction: false,
  },
};
 
export default nextConfig;

import.meta.glob

Turbopack supports the Vite-compatible import.meta.glob API:

app/posts.ts
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:

app/posts.ts
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 turbopackLocalPostcssConfig option 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(), and worker_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):

node_modules/next/dist/docs
01-app/
02-pages/
03-architecture/
index.mdx

The 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:

terminal
npx @next/codemod@canary agents-md

Disable automatic generation when needed:

next.config.ts
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_issues returns compilation warnings and errors for the whole project without requiring an open browser page (#92062).
  • compile_route compiles 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:

.mcp.json
{
  "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-loop verifies changes through the development MCP server and a real browser (#93943).
  • next-cache-components-optimizer improves and verifies the static shell for initial loads and client navigations (#94035).

List or install them with the open skills CLI:

terminal
npx skills add vercel/next.js --list
 
npx skills add vercel/next.js \
  --skill next-dev-loop \
  --skill next-cache-components-optimizer

Rendering 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:

MetricWeb StreamsNode.js streamsChange
Average latency44.5ms29.5ms33.7% lower
Throughput1,064 req/s1,599 req/s50.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:

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:

app/dashboard/error.tsx
'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:

app/error-boundary.tsx
'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:

app/dashboard/page.tsx
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, and sitemap.ts participate 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:

next.config.ts
const nextConfig = {
  enablePrerenderSourceMaps: false,
};
 
export default nextConfig;

Other Developer Updates

  • Client instrumentation for integrations: instrumentationClientInject lets config wrappers inject setup before hydration without editing the application's instrumentation-client.ts file (#93785). Application developers should continue using instrumentation-client.ts directly.
  • 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-paths with src: Build path filtering now works when app or pages is inside the src directory (#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.