Next.js 16 es una release mayor que trae Turbopack como bundler por defecto, reemplaza middleware por proxy.ts, introduce Cache Components y hace todas las APIs de request asíncronas. Si estás actualizando desde Next.js 15, esta guía cubre cada cambio breaking y nueva funcionalidad que necesitas conocer.
proxy.ts reemplaza a middleware.ts
El cambio de nombre más importante en Next.js 16 es que middleware.ts ahora se llama proxy.ts. La función además se ejecuta en el runtime completo de Node.js (no Edge), dándote acceso a toda la API de Node.js:
// proxy.ts (al mismo nivel que app/)
import { NextRequest, NextResponse } from 'next/server';
export function proxy(request: NextRequest) {
const { pathname } = request.nextUrl;
// Detección de idioma con Node.js completo disponible
const locale = detectLocale(request);
// Redireccionar si no hay prefijo de idioma
if (!pathname.startsWith('/es') && !pathname.startsWith('/en')) {
return NextResponse.redirect(
new URL(`/${locale}${pathname}`, request.url)
);
}
return NextResponse.next();
}
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};Diferencias clave con middleware.ts
- Runtime Node.js completo: Puedes usar
node:fs,node:crypto, ORMs y cualquier paquete npm — sin más restricciones del Edge runtime. - Ubicación del archivo: Coloca
proxy.tsal mismo nivel que tu directorioapp/. Si usassrc/, va dentro desrc/. - Misma API: La firma de la función,
NextRequest/NextResponsey matchers funcionan de forma idéntica. - Migración: Renombra
middleware.tsaproxy.tsy actualiza el nombre del export demiddlewareaproxy.
Turbopack es el bundler por defecto
Turbopack es ahora el bundler por defecto en Next.js 16, reemplazando a Webpack. Está escrito en Rust y ofrece tiempos de build drásticamente más rápidos:
- Cold start: ~0.8s vs ~4.2s con Webpack (5x más rápido)
- HMR (Hot Module Replacement): ~15ms vs ~320ms (20x más rápido)
- Build de producción: ~12s vs ~45s para una app de tamaño medio (4x más rápido)
- Escala con el tamaño de la app: La velocidad de HMR no se degrada conforme tu app crece.
Configuración
La configuración de Turbopack ahora es top-level en next.config.ts — ya no está bajo experimental:
// next.config.ts
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
// La config de Turbopack ahora es top-level
turbopack: {
rules: {
'*.svg': {
loaders: ['@svgr/webpack'],
as: '*.js',
},
},
resolveAlias: {
// Resolución de módulos personalizada
},
},
};
export default nextConfig;
Si tenías experimental.turbopack en tu config, simplemente muévelo al nivel superior.
APIs de Request Asíncronas
Todas las APIs con scope de request son ahora asíncronas en Next.js 16. Este es un cambio breaking que afecta a cada componente y route handler que use estas funciones:
// Antes (Next.js 15)
const cookieStore = cookies();
const headersList = headers();
const { id } = params;
const { q } = searchParams;
// Después (Next.js 16)
const cookieStore = await cookies();
const headersList = await headers();
const { id } = await params;
const { q } = await searchParams;Migración automatizada
Next.js proporciona un codemod para automatizar esta migración:
# Ejecutar el codemod de APIs asíncronas
npx @next/codemod@latest next-async-request-api .
Esto encontrará todos los usos de cookies(), headers(), params y searchParams y añadirá await donde sea necesario.
Ejemplos en la práctica
// app/[locale]/page.tsx
export default async function HomePage({
params,
}: {
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
// ...
}
// app/api/auth/route.ts
export async function GET() {
const cookieStore = await cookies();
const token = cookieStore.get('session')?.value;
// ...
}Cache Components con 'use cache'
Los Cache Components reemplazan el experimental PPR (Partial Prerendering) de Next.js 15. Permiten marcar componentes o funciones específicas como cacheables:
// Un Server Component cacheado
'use cache';
import { cacheLife, cacheTag } from 'next/cache';
export async function ProductList() {
cacheLife('hours'); // Cachear durante 1 hora
cacheTag('products'); // Tag para invalidación dirigida
const products = await db.product.findMany();
return (
<ul>
{products.map((p) => (
<li key={p.id}>{p.name} — {p.price}</li>
))}
</ul>
);
}Invalidación dirigida
// app/admin/actions.ts
'use server';
import { revalidateTag } from 'next/cache';
export async function updateProduct(id: string, data: ProductData) {
await db.product.update({ where: { id }, data });
// Invalidar solo componentes con tag 'products'
revalidateTag('products');
}Otros cambios destacados
Node.js 24 LTS
Next.js 16 usa por defecto Node.js 24 LTS. Node.js 18 está deprecado. Asegúrate de actualizar tus entornos de CI y deployment.
Configuración vercel.ts
Ahora puedes configurar tu proyecto Vercel con TypeScript en lugar de JSON:
// vercel.ts
import { routes, type VercelConfig } from '@vercel/config/v1';
export const config: VercelConfig = {
buildCommand: 'npm run build',
framework: 'nextjs',
crons: [{ path: '/api/cleanup', schedule: '0 0 * * *' }],
};cacheHandlers (plural)
La opción de config cacheHandler se renombró a cacheHandlers (plural) para soportar múltiples tipos de handler.
Checklist de Migración
Aquí tienes un checklist rápido para actualizar de Next.js 15 a 16:
- Renombrar
middleware.tsaproxy.tsy actualizar el nombre de la función exportada. - Ejecutar
npx @next/codemod@latest next-async-request-api .para añadirawaita todas las APIs de request. - Mover la config de
experimental.turbopackaturbopacken el nivel superior. - Reemplazar PPR con Cache Components (directiva
'use cache'). - Renombrar
cacheHandleracacheHandlersennext.config.ts. - Actualizar Node.js a 24 LTS en CI/CD y imágenes Docker.
- Testear toda la lógica de middleware bajo el runtime Node.js (sin más restricciones Edge).
Conclusión
Next.js 16 es un paso significativo hacia adelante. Turbopack hace el desarrollo notablemente más rápido, proxy.ts elimina las limitaciones del Edge runtime en middleware, y los Cache Components te dan control granular sobre qué se cachea y cuándo. La ruta de migración está bien soportada con codemods, así que actualizar es directo.