Next.js 16: Novità e Miglioramenti - Release Ottobre 2025
Scopri Next.js 16: Cache Components, Turbopack Stable, React Compiler, proxy.ts, DevTools MCP, React 19.2 e tutte le novità di ottobre 2025.

Next.js 16 è stato rilasciato il 21 ottobre 2025. Questa release introduce Cache Components con direttiva use cache, Turbopack stabile di default (2-5x builds, 10x Fast Refresh), React Compiler integrato, proxy.ts che sostituisce middleware, DevTools MCP per debugging AI-assisted e supporto completo React 19.2.
🎯 Novità Principali
Cache Components & "use cache" Directive
Il più grande cambiamento: caching opt-in esplicito con Partial Prerendering!
❌ Prima - Caching implicito confusing:
// App Router pre-16 - Caching automatico e opaco
export default async function Page() {
const data = await fetch("https://api.example.com/data");
// ❌ Quando cached? Quando revalidated? Unclear!
return <div>{data}</div>;
}
✅ Next.js 16 - use cache esplicito:
"use cache";
export default async function Page() {
// ✅ Cached esplicitamente!
const data = await getData();
return <div>{data}</div>;
}
async function getData() {
const res = await fetch("https://api.example.com/data");
return res.json();
}
Cache a livello component:
import { unstable_cache as cache } from "next/cache";
// ✅ Cache specific component
export async function UserProfile({ userId }: { userId: string }) {
"use cache";
const user = await fetchUser(userId);
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}
Cache a livello function:
// ✅ Cache function specifica
async function getProducts() {
"use cache";
const products = await db.products.findMany();
return products;
}
// Component non cached, ma function si
export default async function ProductsPage() {
const products = await getProducts(); // Cached
const stats = await getStats(); // NOT cached
return <ProductList products={products} stats={stats} />;
}
Partial Prerendering (PPR) Complete:
// layout.tsx - Shell statico
export default function Layout({ children }) {
return (
<html>
<body>
<Header /> {/* Static */}
<Suspense fallback={<Loading />}>
{children} {/* Dynamic */}
</Suspense>
<Footer /> {/* Static */}
</body>
</html>
);
}
// page.tsx - Dynamic content con cache
export default async function Page() {
return (
<>
<StaticHero /> {/* Prerendered */}
<Suspense fallback={<Skeleton />}>
<DynamicFeed /> {/* use cache - instant */}
</Suspense>
</>
);
}
async function DynamicFeed() {
"use cache";
const posts = await getPosts();
return <FeedList posts={posts} />;
}
Configuration - Enable Cache Components:
// next.config.ts
const nextConfig = {
experimental: {
cacheComponents: true, // Enable Cache Components
},
};
export default nextConfig;
Vantaggi Cache Components:
- ✅ Explicit: Sai esattamente cosa è cached
- ✅ Flexible: Cache page, component O function
- ✅ Opt-in: Tutto dynamic di default
- ✅ PPR ready: Completa Partial Prerendering
Turbopack - Stable & Default
Turbopack ora stable e default bundler per TUTTI i progetti!
Performance benchmarks:
# Development
next dev
# Fast Refresh: 10x faster (100ms → 10ms)
# HMR: Instant updates
# Production
next build
# Build time: 2-5x faster
# Large projects: Minutes → Seconds
Filesystem Caching (Beta):
// next.config.ts
const nextConfig = {
experimental: {
turbopackFileSystemCacheForDev: true, // 🚀 Cache su disco!
},
};
export default nextConfig;
Risultato:
- ✅ Cold start: -70% tempo (restart istantaneo)
- ✅ Compile artifacts: Riutilizzati tra sessioni
- ✅ Monorepos: Game changer per grandi codebase
Fallback a Webpack (se necessario):
# Usa Webpack invece di Turbopack
next dev --webpack
next build --webpack
React Compiler Support (Stable!)
React Compiler ora integrato direttamente - auto-memoization!
Setup:
# Install compiler
npm install babel-plugin-react-compiler@latest
// next.config.ts
const nextConfig = {
experimental: {
reactCompiler: true, // ✅ Enable React Compiler
},
};
export default nextConfig;
❌ Prima - Manual memoization:
import { useMemo, useCallback } from "react";
function TodoList({ todos, onToggle }) {
// ❌ Manual memoization everywhere!
const sortedTodos = useMemo(
() => todos.sort((a, b) => a.priority - b.priority),
[todos]
);
const handleToggle = useCallback((id) => onToggle(id), [onToggle]);
return (
<ul>
{sortedTodos.map((todo) => (
<TodoItem key={todo.id} todo={todo} onToggle={handleToggle} />
))}
</ul>
);
}
✅ React Compiler - Automatic:
function TodoList({ todos, onToggle }) {
// ✅ Compiler auto-memoize!
const sortedTodos = todos.sort((a, b) => a.priority - b.priority);
const handleToggle = (id) => onToggle(id);
return (
<ul>
{sortedTodos.map((todo) => (
<TodoItem key={todo.id} todo={todo} onToggle={handleToggle} />
))}
</ul>
);
}
// Compiler genera useMemo/useCallback automaticamente!
Tradeoff:
- ✅ Runtime: -30% re-renders
- ⚠️ Build time: +10-15% (usa Babel)
- 💡 Worth it: Per UI-heavy apps
proxy.ts Replaces middleware.ts
Nuovo proxy.ts sostituisce middleware.ts per chiarire network boundary!
Migration:
// ❌ middleware.ts (old)
import { NextRequest, NextResponse } from "next/server";
export function middleware(request: NextRequest) {
// Redirect logic
if (request.nextUrl.pathname === "/old") {
return NextResponse.redirect(new URL("/new", request.url));
}
return NextResponse.next();
}
export const config = {
matcher: "/api/:path*",
};
// ✅ proxy.ts (new)
import { NextRequest, NextResponse } from "next/server";
export function proxy(request: NextRequest) {
// Same logic, clearer name!
if (request.nextUrl.pathname === "/old") {
return NextResponse.redirect(new URL("/new", request.url));
}
return NextResponse.next();
}
export const config = {
matcher: "/api/:path*",
};
Vantaggi proxy.ts:
- ✅ Clearer name: "Proxy" = network boundary
- ✅ Node.js runtime: Gira su Node (non Edge)
- ✅ Explicit: Chiaro cosa fa
Migration automatica:
# Rename automaticamente
npx @next/codemod@latest proxy-migration
Next.js DevTools MCP (Model Context Protocol)
AI-assisted debugging integrato direttamente!
Setup:
// next.config.ts
const nextConfig = {
experimental: {
devToolsMCP: true, // Enable MCP
},
};
export default nextConfig;
Come funziona:
# Start dev con MCP
next dev
# AI agent può:
# - Ispezionare route structure
# - Analizzare cache behavior
# - Debug build issues
# - Suggest optimizations
Esempio interaction:
You: "Why is this page slow?"
AI (via MCP):
1. Analyzing route /dashboard...
2. Found: 3 uncached data fetches
3. Recommendation: Add 'use cache' to getUserData()
4. Expected improvement: -60% load time
Vantaggi MCP:
- ✅ Context-aware: AI conosce app structure
- ✅ Debug faster: Diagnosi automatica
- ✅ Learn: Spiega behavior Next.js
- ✅ Suggestions: Fix actionable
Improved Caching APIs
Nuove API per granular cache control:
1. revalidateTag con profiles:
import { revalidateTag } from "next/cache";
// ❌ Prima - nukes tutto
await revalidateTag("products");
// ✅ Next.js 16 - granular revalidation
await revalidateTag("products", "max"); // Keep long
await revalidateTag("news", "hours"); // Hourly
await revalidateTag("prices", { revalidate: 3600 }); // Custom
2. updateTag - Instant revalidation:
"use server";
import { updateTag } from "next/cache";
export async function updateUserProfile(id: string, data: UserData) {
await db.users.update(id, data);
// ✅ Instant cache update (no wait!)
updateTag(`user-${id}`);
// UI aggiornata IMMEDIATAMENTE
}
3. refresh() - Force fresh fetch:
import { refresh } from "next/cache";
export async function getLiveData() {
// ✅ Bypass cache completamente
refresh();
const data = await fetch("https://api.example.com/live");
return data.json();
}
Real-world example:
// Dashboard con mixed caching
export default async function Dashboard() {
return (
<>
<Stats /> {/* Cached "max" */}
<RecentActivity /> {/* Cached "hours" */}
<LiveMetrics /> {/* refresh() - always fresh */}
</>
);
}
async function Stats() {
"use cache";
const stats = await getStats();
return <StatsCard data={stats} />;
}
async function RecentActivity() {
"use cache";
const activity = await getActivity();
return <ActivityFeed items={activity} />;
}
async function LiveMetrics() {
refresh(); // No cache!
const metrics = await getLiveMetrics();
return <MetricsChart data={metrics} />;
}
Enhanced Routing
Routing completamente rifattorizzato per performance!
1. Layout Deduplication:
// app/layout.tsx - Downloaded ONCE
export default function RootLayout({ children }) {
return (
<html>
<body>
<Nav /> {/* Shared layout */}
{children}
</body>
</html>
)
}
// Prefetch 10 links con stesso layout
<Link href="/page1" /> {/* Downloads layout + page1 */}
<Link href="/page2" /> {/* Only page2! Layout cached */}
<Link href="/page3" /> {/* Only page3! */}
// ✅ Layout downloaded ONCE, not 10 times!
2. Incremental Prefetching:
// Prefetch intelligente
<Link href="/products" prefetch={true}>
Products
</Link>
// Next.js prefetches SOLO missing data
// - Layout già in cache? Skip
// - Page già in cache? Skip
// - Fetch only NEW data needed
3. Viewport-aware Prefetch Cancellation:
// Link esce da viewport
<Link href="/page"> {/* Prefetch started */}
// User scrolls, link not visible
// ✅ Prefetch CANCELLED automaticamente!
Performance impact:
- ✅ -40% network: Meno dati scaricati
- ✅ +60% navigation speed: Layout cached
- ✅ Smarter: Cancel unused prefetch
🚀 React 19.2 Support
Next.js 16 App Router usa React 19.2!
Nuove feature React 19.2:
1. View Transitions:
import { useTransition } from "react";
export default function Gallery() {
const [isPending, startTransition] = useTransition();
const [activeId, setActiveId] = useState(1);
return (
<div>
{images.map((img) => (
<img
key={img.id}
src={img.src}
onClick={() => {
// ✅ Smooth transition animation!
startTransition(() => {
setActiveId(img.id);
});
}}
style={{
viewTransitionName: `image-${img.id}`,
}}
/>
))}
</div>
);
}
2. useEffectEvent:
import { useEffectEvent } from "react";
function Chat({ serverUrl, roomId }) {
const [message, setMessage] = useState("");
// ✅ Extract non-reactive logic!
const onConnected = useEffectEvent(() => {
showNotification("Connected!");
sendAnalytics(message); // Can use message without re-running effect!
});
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.on("connected", onConnected);
connection.connect();
return () => connection.disconnect();
}, [serverUrl, roomId]); // message NOT in deps!
}
3. Activity (Background UI):
import { Activity } from "react";
export default function App() {
const [activeTab, setActiveTab] = useState("home");
return (
<>
<Tabs active={activeTab} onChange={setActiveTab} />
{/* ✅ Background tabs mantengono state! */}
<Activity mode={activeTab === "home" ? "visible" : "hidden"}>
<HomeTab />
</Activity>
<Activity mode={activeTab === "profile" ? "visible" : "hidden"}>
<ProfileTab />
</Activity>
</>
);
}
🔧 Build Adapters API (Alpha)
Custom adapters per build process!
// my-adapter.ts
export default function myAdapter(options) {
return {
name: "my-custom-adapter",
async build(buildContext) {
// Custom build logic
console.log("Building for custom platform...");
// Access build artifacts
const { pages, publicDir } = buildContext;
// Deploy to custom infra
await deployToCustomPlatform(pages);
},
};
}
// next.config.ts
const nextConfig = {
experimental: {
adapterPath: require.resolve("./my-adapter.ts"),
},
};
Use cases:
- ✅ Deploy a Cloudflare Workers
- ✅ Custom server infrastructure
- ✅ Specialized hosting platforms
- ✅ Multi-platform builds
📊 Improved Logging
Build logs ridisegnati completamente!
# next build - New logs
▲ Next.js 16.0.0
✓ Compiled successfully
✓ Optimizing...
Build Breakdown:
├─ Pages 250ms (12 pages)
├─ App Router 420ms (8 routes)
├─ Static 180ms (15 files)
└─ Total 850ms
Route Analysis:
├─ / 150ms ✓ Static
├─ /dashboard 220ms ⚡ PPR
└─ /api/* 80ms ⚡ Dynamic
Cache:
├─ use cache hits: 24
└─ revalidations: 3
✨ Build complete!
Vantaggi:
- ✅ Clearer: Vedi dove va tempo
- ✅ Actionable: Ottimizza bottleneck
- ✅ Color-coded: Più leggibile
⚠️ Breaking Changes
Rimosso
- ❌ AMP Support: Completamente rimosso
- ❌ next lint: Deprecato (usa eslint direttamente)
- ❌ Link legacyBehavior: Rimosso
Migration
1. Link migration:
// ❌ Rimosso
<Link href="/about" legacyBehavior>
<a>About</a>
</Link>
// ✅ Modern
<Link href="/about">About</Link>
2. Middleware → proxy.ts:
# Rename file
mv src/middleware.ts src/proxy.ts
# Update export
# export function middleware → export function proxy
3. PPR config update:
// ❌ Old
const nextConfig = {
experimental: {
ppr: true,
},
};
// ✅ New
const nextConfig = {
experimental: {
cacheComponents: true,
},
};
📊 Performance Benchmarks
| Metrica | Next.js 15 | Next.js 16 | Improvement |
|---|---|---|---|
| Fast Refresh | 100ms | 10ms | 10x |
| Build Time | 45s | 12s | 3.75x |
| Navigation | 200ms | 80ms | 2.5x |
| Cold Start (dev) | 8s | 2s | 4x |
| Network (prefetch) | 100% | 60% | -40% |
🔄 Migration Guide
Upgrade
# Automatic upgrade
npx @next/codemod@canary upgrade latest
# Manual
npm install next@latest react@latest react-dom@latest
# New project
npx create-next-app@latest
Enable Features
// next.config.ts
const nextConfig = {
experimental: {
// Cache Components
cacheComponents: true,
// Turbopack FS cache
turbopackFileSystemCacheForDev: true,
// React Compiler
reactCompiler: true,
// DevTools MCP
devToolsMCP: true,
},
};
export default nextConfig;
Requirements
- ✅ Node.js: 20.9+
- ✅ TypeScript: 5.1+
- ✅ React: 19.2+
💡 Conclusioni
Next.js 16 è una release developer-first:
✅ Cache Components - Caching finalmente esplicito e controllabile ✅ Turbopack - 10x Fast Refresh, 2-5x builds, default per tutti ✅ React Compiler - Auto-memoization senza overhead ✅ proxy.ts - Network boundary chiaro e explicit ✅ DevTools MCP - AI-assisted debugging integrato ✅ Enhanced Routing - -40% network, +60% navigation speed ✅ React 19.2 - View Transitions, useEffectEvent, Activity ✅ Better DX - Logs chiari, build adapters, performance