O Next.js 16 não é uma atualização incremental. É uma mudança de fundação. O bundler padrão agora é o Turbopack, o modelo de cache foi reescrito do zero com Cache Components, e até o nome do arquivo de middleware mudou. Se você trabalha com Next.js em produção, essa versão exige atenção.
Neste guia, vamos passar por cada novidade relevante, entender o que muda na prática e ver exemplos de código para cada recurso. O objetivo é que você termine a leitura sabendo exatamente o que precisa fazer para migrar — ou para começar um projeto novo já com a arquitetura certa.
O que muda no Next.js 16
A versão 16 consolida mudanças que vinham sendo testadas em betas desde meados de 2025. Três pilares definem essa release:
- Turbopack estável e padrão — Não é mais opt-in. Todo projeto novo já usa Turbopack por padrão, com builds de produção 2 a 5 vezes mais rápidos
- Cache Components — O cache implícito das versões anteriores foi substituído por um modelo explícito baseado na diretiva
"use cache" - proxy.ts — O
middleware.tsfoi depreciado em favor doproxy.ts, que roda no runtime Node.js
Além disso, o Next.js 16 traz React 19.2 com View Transitions, novas APIs de cache (updateTag, refresh), React Compiler estável e melhorias significativas no sistema de roteamento.
Para atualizar, o caminho mais seguro é usar o codemod oficial:
npx @next/codemod@canary upgrade latest
Cache Components: o novo modelo de cache
Essa é a mudança mais significativa do Next.js 16. Nas versões anteriores, o cache era implícito — o framework decidia automaticamente o que era estático e o que era dinâmico. Isso gerava comportamentos confusos e bugs sutis em produção.
Agora, o cache é inteiramente opt-in. Todo código dentro de páginas, layouts e API routes roda de forma dinâmica por padrão. Você opta pelo cache explicitamente usando a diretiva "use cache".
Como funciona
A diretiva "use cache" pode ser aplicada em três níveis: páginas inteiras, componentes individuais e funções. O compilador gera automaticamente as chaves de cache com base nas dependências.
// Uma função com cache explícito
"use cache"
export async function getProductList() {
const products = await db.products.findMany();
return products;
}
Cache Components completam a história do Partial Prerendering (PPR), que foi introduzido em 2023. Com PPR, o Next.js pode renderizar partes de uma página estaticamente e outras dinamicamente. Cache Components dão ao desenvolvedor o controle sobre quais partes são cacheadas.
Para habilitar Cache Components no seu projeto:
// next.config.ts
const nextConfig = {
cacheComponents: true,
};
export default nextConfig;
O que muda na prática
Se você usava experimental.ppr ou experimental.dynamicIO, essas flags foram removidas. O caminho agora é cacheComponents: true. A migração é direta — o modelo mental é mais simples porque você decide explicitamente o que cacheia.
A flag experimental.ppr e a exportação export const experimental_ppr por rota também foram removidas. Tudo foi consolidado no modelo de Cache Components.
Turbopack como bundler padrão
O Turbopack saiu do beta e agora é o bundler padrão para todos os projetos Next.js 16 — tanto em desenvolvimento quanto em produção. Os números são expressivos:
- Fast Refresh até 10x mais rápido
- Builds de produção 2 a 5x mais rápidos
- Mais de 50% das sessões de desenvolvimento no Next.js 15.3+ já rodavam com Turbopack antes da versão 16
Em testes internos da Vercel, um build que levava 24.5 segundos com Webpack agora completa em 5.7 segundos com Turbopack.
File System Caching
Uma novidade em beta é o cache de sistema de arquivos, que armazena artefatos do compilador em disco entre reinicializações. Em projetos grandes, isso reduz significativamente o tempo de startup.
// next.config.ts
const nextConfig = {
experimental: {
turbopackFileSystemCacheForDev: true,
},
};
export default nextConfig;
Continuando com Webpack
Se o seu projeto depende de configurações customizadas de Webpack que ainda não são suportadas pelo Turbopack, você pode voltar ao bundler anterior:
next dev --webpack
next build --webpack
O Webpack continua disponível, mas não é mais o padrão.
O fim do middleware: bem-vindo ao proxy.ts
O arquivo middleware.ts foi depreciado. O substituto é o proxy.ts, que faz a mesma coisa com uma diferença importante: roda no runtime Node.js, não no Edge Runtime.
A motivação é clareza. O nome "middleware" era ambíguo — sugeria um middleware de aplicação, quando na verdade atuava como proxy de rede. O novo nome reflete melhor a função real do arquivo.
A migração é simples:
// Antes: middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
return NextResponse.redirect(new URL('/home', request.url));
}
// Depois: proxy.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export default function proxy(request: NextRequest) {
return NextResponse.redirect(new URL('/home', request.url));
}
Duas mudanças: o nome do arquivo muda de middleware.ts para proxy.ts, e a função exportada muda de middleware para proxy (tanto default export quanto named export proxy são válidos). A lógica interna permanece idêntica.
O middleware.ts ainda funciona para casos de uso com Edge Runtime, mas está depreciado e será removido em versões futuras.
Novas APIs de cache: updateTag, refresh e revalidateTag
O Next.js 16 refinou as APIs de controle de cache para dar mais clareza sobre quando e como os dados são revalidados.
revalidateTag() atualizado
A função revalidateTag() agora exige um segundo argumento — um perfil de cacheLife — para habilitar o comportamento stale-while-revalidate (SWR):
import { revalidateTag } from 'next/cache';
// Com perfil de cache (recomendado)
revalidateTag('blog-posts', 'max');
// Com perfis diferentes conforme a necessidade
revalidateTag('news-feed', 'hours');
revalidateTag('analytics', 'days');
// Com tempo customizado
revalidateTag('products', 'hours');
O perfil 'max' é recomendado para a maioria dos casos — os usuários recebem dados cacheados imediatamente enquanto o Next.js revalida em background.
updateTag() novo
A função updateTag() é exclusiva de Server Actions e oferece semântica read-your-writes: expira o cache e lê dados frescos na mesma requisição.
'use server';
import { updateTag } from 'next/cache';
export async function updateUserProfile(userId: string, profile: Profile) {
await db.users.update(userId, profile);
updateTag(`user-${userId}`);
}
Quando o usuário edita seu perfil e salva, ele vê a mudança imediatamente. Sem delay, sem estado intermediário.
refresh() novo
A função refresh() atualiza apenas dados não-cacheados, sem tocar no cache existente:
'use server';
import { refresh } from 'next/cache';
export async function markNotificationAsRead(notificationId: string) {
await db.notifications.markAsRead(notificationId);
refresh();
}
Use refresh() para dados dinâmicos como contadores de notificação, métricas em tempo real ou indicadores de status que não estão no cache.
React 19.2: View Transitions, Activity e useEffectEvent
O App Router no Next.js 16 inclui React 19.2 com três features que merecem atenção.
View Transitions
View Transitions permitem animar elementos que mudam durante uma navegação ou Transition. É a mesma API de View Transitions do navegador, mas integrada ao modelo de renderização do React.
Na prática, você consegue criar transições suaves entre páginas sem bibliotecas externas de animação. O React coordena as animações com o ciclo de renderização, evitando flashes de conteúdo.
Activity
O componente Activity permite renderizar UI em background, escondendo com display: none enquanto mantém estado e limpa Effects. É útil para tabs, modais e navegação onde você quer preservar o estado de componentes que não estão visíveis.
useEffectEvent
O hook useEffectEvent resolve um problema clássico: extrair lógica não-reativa de Effects. Quando você tem um Effect que depende de valores que mudam frequentemente mas não devem re-executar o Effect, useEffectEvent encapsula essa lógica.
import { useEffectEvent } from 'react';
function ChatRoom({ roomId, theme }) {
const onMessage = useEffectEvent((message) => {
showNotification(message, theme);
});
useEffect(() => {
const connection = createConnection(roomId);
connection.on('message', onMessage);
return () => connection.disconnect();
}, [roomId]);
}
O Effect depende apenas de roomId, mas a função onMessage sempre acessa o theme mais recente sem causar re-execução do Effect.
Breaking changes que você precisa conhecer
O Next.js 16 traz mudanças que quebram compatibilidade. As mais impactantes:
Versões mínimas:
- Node.js 20.9+ (Node.js 18 não é mais suportado)
- TypeScript 5.1+
Params e searchParams agora são async:
// Antes (síncrono - não funciona mais)
export default function Page({ params }) {
const { slug } = params;
}
// Depois (async obrigatório)
export default async function Page({ params }) {
const { slug } = await params;
}
O mesmo vale para cookies(), headers() e draftMode() — todos exigem await.
Remoções notáveis:
- Suporte a AMP completamente removido
- Comando
next lintremovido — use ESLint ou Biome diretamente serverRuntimeConfigepublicRuntimeConfigremovidos em favor de variáveis de ambiente- Parallel routes agora exigem
default.jsexplícito em cada slot
React Compiler estável (mas não padrão):
O React Compiler 1.0 está integrado ao Next.js 16, mas não é habilitado por padrão. A razão é que ele depende de Babel, o que aumenta o tempo de compilação:
// next.config.ts
const nextConfig = {
reactCompiler: true,
};
export default nextConfig;
A configuração saiu de experimental.reactCompiler para o nível raiz reactCompiler.
Conclusão
O Next.js 16 é uma versão que consolida a direção do framework. O Turbopack como padrão, os Cache Components substituindo o cache implícito e o proxy.ts no lugar do middleware são decisões que simplificam o modelo mental — mesmo que exijam trabalho de migração.
Se você está começando um projeto novo, use Next.js 16 direto. A base está mais limpa e previsível do que qualquer versão anterior.
Se você está migrando um projeto existente, comece pelo codemod automático e depois revise manualmente os pontos que ele não consegue cobrir: params async, remoção de AMP se aplicável e a renomeação de middleware.ts para proxy.ts. O modelo de Cache Components pode ser adotado incrementalmente — não precisa migrar tudo de uma vez.
A combinação de Turbopack rápido, cache explícito e React 19.2 com View Transitions coloca o Next.js 16 como a versão mais madura do framework até agora.