Capítulo 95 de 456

Version 16

Core Idea

Guia de upgrade de Next.js 15 para 16 — a versão que estabiliza o Turbopack como padrão, remove totalmente o acesso síncrono às Async Request APIs, renomeia middleware para proxy, estabiliza cacheLife/cacheTag/updateTag, e recomenda um fluxo assistido por agente de IA.

Key Concepts

  • Upgrade via agente de IA (recomendado): prompt oficial pede ao agente pra ler AGENTS.md (docs versionadas em node_modules/next/dist/docs/), seguir o guia de upgrade como fonte de verdade, rodar o codemod, explicar o plano, e verificar em runtime com a skill next-dev-loop (Next.js 16.3+ com Turbopack).
  • npx @next/codemod@canary agents-md: gera/atualiza AGENTS.md com bloco gerenciado apontando para docs versionadas, evitando que o agente use conhecimento desatualizado sobre a API.
  • Codemod upgrade latest: atualiza config do Turbopack, migra next lint→ESLint CLI, migra middlewareproxy, remove prefixo unstable_, remove experimental_ppr. NÃO roda o codemod de Async Request APIs — rodar next-async-request-api separadamente se ainda usa acesso síncrono legado da v15.
  • Requisitos mínimos: Node.js 20.9+ (LTS; Node 18 não suportado), TypeScript 5.1+, browsers Chrome/Edge/Firefox 111+, Safari 16.4+.
  • Turbopack por padrão: next dev e next build usam Turbopack sem flag; --turbopack/--turbo não são mais necessários. Se houver config webpack customizada, next build falha por padrão (proteção contra misconfiguration) — opções: --turbopack (ignora webpack config), migrar config para Turbopack, ou --webpack para manter Webpack.
  • turbopack config no top-level: experimental.turbopack saiu do experimental e virou turbopack na raiz do next.config.
  • turbopack.resolveAlias: equivalente ao resolve.fallback do Webpack para silenciar módulos Node.js nativos (fs) em bundles client-side, e para lidar com o prefixo legado ~ do Sass (não suportado pelo Turbopack).
  • Turbopack File System Caching: artefatos de compilação persistidos em disco entre execuções, habilitado por padrão via experimental.turbopackFileSystemCacheForDev/...ForBuild.
  • Async Request APIs totalmente síncronas removidas: cookies(), headers(), draftMode(), params, searchParams (e props de opengraph-image/twitter-image/icon/apple-icon) só podem ser acessadas de forma assíncrona — a compatibilidade temporária da v15 (UnsafeUnwrapped*) acabou.
  • npx next typegen: gera helpers PageProps, LayoutProps, RouteContext para migração type-safe para params/searchParams assíncronos (disponível desde 15.5).
  • revalidateTag exige segundo argumento: agora precisa de um perfil cacheLife (ex. revalidateTag('posts', 'max')); forma de um argumento só é deprecated e gera erro de TypeScript.
  • updateTag: nova API exclusiva de Server Actions com semântica read-your-writes — expira e refresca dados na mesma requisição, diferente de revalidateTag (stale-while-revalidate).
  • refresh: refresca o client router a partir de uma Server Action, sem necessariamente invalidar cache.
  • cacheLife/cacheTag estáveis: prefixo unstable_ não é mais necessário.
  • middlewareproxy: nome de arquivo e export deprecados; proxy roda só em runtime nodejs (não suporta edge — quem precisa de edge deve continuar usando middleware por enquanto); flags de config renomeadas (skipMiddlewareUrlNormalizeskipProxyUrlNormalize).
  • PPR via cacheComponents: a flag experimental experimental_ppr/experimental.ppr foi removida; PPR agora se habilita com cacheComponents: true, com comportamento diferente das canaries da v15.
  • next/image: query strings em imagens locais: agora exigem images.localPatterns.search configurado explicitamente, prevenindo ataques de enumeração.

Code Examples

npx @next/codemod@canary upgrade latest
  • O que demonstra: comando principal de upgrade automatizado para a v16.
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}
  • O que demonstra: scripts simplificados sem --turbopack, já que é o padrão na v16.
const nextConfig: NextConfig = {
  turbopack: {
    resolveAlias: {
      fs: { browser: './empty.ts' },
    },
  },
}
  • O que demonstra: silenciar erro Module not found: Can't resolve 'fs' no client bundle via turbopack.resolveAlias (equivalente ao resolve.fallback do Webpack).
'use server'
import { updateTag } from 'next/cache'

export async function updateUserProfile(userId: string, profile: Profile) {
  await db.users.update(userId, profile)
  updateTag(`user-${userId}`) // usuário vê a mudança imediatamente
}
  • O que demonstra: updateTag para read-your-writes imediato, em contraste com revalidateTag('posts', 'max') que aceita staleness temporária.
mv middleware.ts proxy.ts
export function proxy(request: Request) {}
  • O que demonstra: renomeação de arquivo e função exigida pela deprecação de middleware.

Reference Tables

RequisitoMudança
Node.jsMínimo 20.9.0 (LTS); Node 18 não suportado
TypeScriptMínimo 5.1.0
BrowsersChrome/Edge/Firefox 111+, Safari 16.4+
O que o codemod upgrade fazCobertura
Atualiza next.config.js pra nova config turbopackSim
Migra next lint → ESLint CLISim
Migra middlewareproxySim
Remove prefixo unstable_ de APIs estabilizadasSim
Remove experimental_ppr do Route Segment ConfigSim
Migra acesso síncrono legado a cookies()/params/etc.Não — rodar next-async-request-api à parte

Anti-patterns

  • Manter --turbopack/--turbo nos scripts após a v16: redundante, já que é o padrão; não é erro, mas é ruído.
  • Rodar next build com config webpack customizada sem decidir explicitamente o caminho: falha por padrão — escolher entre --turbopack (ignora webpack), migrar config, ou --webpack (mantém Webpack).
  • Usar sintaxe Sass legada ~pacote/arquivo: Turbopack não suporta o prefixo ~; usar import direto (@import 'bootstrap/dist/css/bootstrap.min.css') ou resolveAlias: { '~*': '*' }.
  • Assumir que revalidateTag('tag') de um argumento só ainda funciona: agora requer perfil cacheLife como segundo argumento.
  • Continuar usando middleware com runtime edge esperando que proxy seja um rename direto: proxy só roda em nodejs; quem depende de edge deve manter middleware até orientação futura.

Key Takeaways

  1. O caminho recomendado é o fluxo assistido por IA com AGENTS.md apontando para docs versionadas — evita o agente usar conhecimento desatualizado sobre APIs que mudaram.
  2. O codemod upgrade latest cobre a maior parte mecânica, mas não migra acesso síncrono legado — rode next-async-request-api separadamente se necessário.
  3. Turbopack é o padrão agora; webpack customizado exige decisão explícita para não quebrar o build.
  4. Três novas/estabilizadas APIs de cache mudam a forma de invalidar dados: revalidateTag (agora com perfil obrigatório), updateTag (read-your-writes), refresh (refresh de router sem invalidar cache).
  5. proxy substitui middleware mas com restrição de runtime (nodejs apenas) — não é drop-in replacement para quem usa edge.

Connects To

  • Version 15 (ch094): origem das Async Request APIs e do período de compatibilidade síncrona que a v16 encerra.
  • Codemods (ch092): agents-md, upgrade, next-async-request-api, middleware-to-proxy cobrem partes específicas desta migração.
  • Rendering Philosophy (ch075): cacheComponents (novo caminho de PPR) é a materialização prática dessa filosofia.
  • Redirecting (ch074): proxy.js é o mesmo arquivo referenciado lá, agora com nome atualizado.