Next.js 16, released in October 2025, is one of the most architecturally significant releases in the framework's history. Turbopack is now the default bundler, the caching model has been completely rethought with Cache Components, and a new proxy.ts file replaces middleware for network-level concerns. Let's dig into what changed and what it means for your applications.
Turbopack Is Now Default
After years of development and a beta period in Next.js 15, Turbopack is now the default bundler for all new Next.js projects — in both development and production. Webpack is still available as a fallback, but Turbopack is where the investment is going.
The practical impact is significant:
- Development — Hot Module Replacement (HMR) is substantially faster, especially in large codebases. Turbopack uses incremental computation and persistent caching (now stored on disk between restarts) to minimize rebuild times.
- Production builds — Build times are reduced for most projects, though the improvement varies by codebase complexity. Tree shaking, code splitting, and minification are handled natively.
- Configuration — Most webpack configurations have Turbopack equivalents, but some less common plugins may need alternatives. Check the migration guide for your specific plugins.
Cache Components
The biggest conceptual change in Next.js 16 is the new caching model built around Cache Components and the use cache directive. This replaces the previous approach where Next.js aggressively cached everything by default (which caused confusion about when data was fresh vs. stale).
Now, caching is explicit and granular. You opt in to caching at the component or function level:
Using the use cache directive
async function ProductPrice({ id }: { id: string }) {
"use cache";
const product = await db.product.findUnique({ where: { id } });
return <span>${product?.price}</span>;
}
// With cache lifetime configuration
async function BlogPosts() {
"use cache";
cacheLife("hours");
const posts = await db.post.findMany({ take: 10 });
return (
<ul>
{posts.map(post => <li key={post.id}>{post.title}</li>)}
</ul>
);
}
Cache Components work with Partial Pre-Rendering (PPR), which lets you serve a static shell instantly while dynamic parts stream in. The combination means you get instant navigation (cached static parts load immediately) with fresh data (dynamic parts fetch on demand).
proxy.ts Replaces Middleware
Next.js 16 introduces proxy.ts as the recommended way to handle request interception, replacing middleware.ts. The key difference: proxy.ts runs on the Node.js runtime (not Edge), making your full Node.js toolbox available:
proxy.ts
import type { NextRequest } from "next/server";
export function GET(request: NextRequest) {
// Auth check with full Node.js APIs available
const token = request.cookies.get("session")?.value;
if (!token && request.nextUrl.pathname.startsWith("/dashboard")) {
return Response.redirect(new URL("/login", request.url));
}
}
export function POST(request: NextRequest) {
// Rate limiting, CSRF checks, etc.
}
The proxy file makes the network boundary explicit: it's where requests enter your application, and it's where you handle cross-cutting concerns like authentication, redirects, and rate limiting. Separating this from the rest of your application logic is cleaner than mixing it into middleware that also handled other concerns.
DevTools MCP
Next.js 16 ships with a DevTools MCP integration — a Model Context Protocol server that lets AI coding assistants (like Claude Code) diagnose issues, explain behavior, and suggest fixes within your Next.js application. When running in development mode, the MCP server exposes your application's routing, caching, and rendering state as structured data that AI tools can query.
This is a practical example of how MCP is being integrated into developer tools, and it's particularly useful for debugging caching behavior and understanding why a page is rendering as static vs. dynamic.
Other Notable Changes
- Async Request APIs only — Synchronous access to request-time APIs (
params,searchParams,cookies,headers) is fully removed. All access must be async withawait. - Typed Routes — Routes now generate TypeScript types from your file structure, so
<Link href="/invalld-path">is caught at compile time. - React 19.2 support — Including the stable React Compiler for automatic memoization.
Upgrading from Next.js 15
The migration path is well-documented. The main areas to address:
- Run the codemod:
npx @next/codemod@latest upgrade latest - Move
middleware.tslogic toproxy.ts - Audit your caching assumptions — pages that were auto-cached in Next.js 15 may need explicit
"use cache"directives - Ensure all request API access is async
