Três semanas atrás eu estava no escritório da Seahawk numa quinta à tarde, bem confiante de que a atualização do Next.js 15 para 16 em um dos meus sites de portfólio pessoal levaria no máximo quarenta minutos. Levou o resto do dia. E honestamente? O changelog não prepara você bem para as partes que realmente quebram.
Construí e lancei mais de 12.000 sites até agora. Não estou dizendo isso para me gabar, estou dizendo porque já fiz migrations suficientes para saber quando o guia oficial de upgrade está encobrindo algo. Next.js 16 encobre algumas coisas. Então aqui estão minhas anotações reais, escritas da forma como eu gostaria que alguém tivesse escrito para mim.
---
Por Que Me Dei ao Trabalho de Atualizar
Turbopack. Essa é a resposta curta.
A resposta mais longa é que dois dos meus sites estavam no Next.js 14, um já estava na 15, e eu estava acompanhando a história do Turbopack por cerca de dezoito meses. A versão 16 é o primeiro lançamento onde Turbopack está ativado por padrão no next dev. Isso não é um detalhe menor. Em uma construção de e-commerce de médio porte que fiz para um cliente de moda no ano passado, os tempos de inicialização a frio em desenvolvimento eram brutais, estamos falando de 12 a 18 segundos no primeiro carregamento. Se Turbopack realmente reduzir isso, vale a pena a dor da migração.
Spoiler: isso reduz. No mesmo tipo de projeto, estou vendo 3 a 4 segundos de inicialização a frio. Isso é real.
Mas o caminho para chegar lá tem algumas arestas afiadas.
---
O Comando de Atualização Real (e O Que Executar Primeiro)
Antes de tocar em qualquer coisa, execute uma auditoria completa da sua configuração atual. Uso npx @next/codemod@latest religiosamente agora. Não vai pegar tudo, mas pega as renomeações óbvias e as chamadas de API descontinuadas. Execute, faça commit do resultado, depois atualize seu package.json.
A atualização em si:
- Atualize next,
reactereact-dompara suas versões de destino nopackage.json - Execute
npm install(oupnpm installse você for sensato, estou usando pnpm há dois anos) - Execute o codemod:
npx @next/codemod@latest upgrade - Inicie
next deve leia cada aviso antes de tocar em um único componente - Corrija problemas de configuração antes de corrigir problemas de componentes, a ordem importa aqui
O passo do codemod é onde vi pessoas tropeçarem. Elas pulam, enfrentam três erros separados, e passam uma hora caçando coisas que teriam sido corrigidas automaticamente. Não pule isso.
---
Mudanças no next.config.js Que Vão Te Morder
Essa foi a primeira grande surpresa para mim. A API de configuração mudou mais do que esperava.
O bloco `experimental` está mais enxuto agora
Vários flags que viviam no experimental há um ou dois anos foram promovidos para estável (e movidos para o nível superior) ou removidos completamente. Os dois que encontrei pessoalmente:
experimental.appDir, gone. App Router é apenas o padrão agora. Se você tiver isso na sua config, vai gerar um aviso (e em algumas configurações, um erro mesmo).- experimental.serverComponentsExternalPackages, promovido para
serverExternalPackagesno nível superior da sua config.
Esse segundo pegou em um site que usa Prisma. A build estava falhando silenciosamente no server bundle e passei provavelmente quarenta minutos olhando pro arquivo errado antes de notar. Confira seu next.config.js de cima a baixo antes de asumir que o problema é um componente.
A config do Turbopack fica em um lugar novo
Se você tinha qualquer config customizada do Webpack e está migrando para Turbopack (o que você vai fazer, já que é o padrão para dev agora), precisa saber que sua função webpack() no next.config.js não aplica quando Turbopack está rodando. Só aplica durante next build, que ainda usa Webpack.
Isso importa se você tinha handling customizado de SVG (eu uso SVGR na maioria dos projetos), aliases de módulo customizados, ou qualquer config de loader. Você vai precisar replicar isso no novo bloco de config do turbopack. A documentação de configuração do Next.js Turbopack é bem decent nesse, vale a leitura antes de asumir que algo quebrou.
---
React 19 Compatibility: A Armadilha Silenciosa
Next.js 16 vem com React 19 como sua peer dependency. Se você está atualizando de Next.js 14 (pulando a 15), está pulando duas versões major do React de uma vez. É aí que as coisas ficam quentes.
O maior problema que enfrentei foi com bibliotecas de componentes terceirizadas mais antigas. Eu tinha um site do cliente usando uma library de tabelas que internamente usava ReactDOM.render(). React 19 removeu aquela API completamente, era deprecated desde React 18 mas ainda funcionava. Na 19, joga erro. Pesado.
Passei uma terça-feira de manhã nisso. A mensagem de erro não aponta imediatamente pra biblioteca; só te diz que ReactDOM.render não é mais suportado. Rode npm ls react pra ver quais pacotes na sua árvore têm declarações conflitantes de peer dependency do React. Esse comando sozinho me economizou provavelmente duas horas de adivinhação.
Alguns padrões que vale conhecer especificamente para React 19:
forwardRefnão é mais necessário pra passar refs; refs agora são um prop regular. Componentes antigos usandoforwardRefainda funcionam, mas você vai ver avisos de deprecation.use()é estável agora e genuinamente útil para dados assincronos em client components. Comecei a usar no lugar deuseEffect+ state pra fetches diretos.- Server Actions têm requisitos de tipo mais apertados. Se você tinha algo com tipagem frouxa nas suas assinaturas de action, TypeScript vai achar agora.
---
App Router: O Que Mudou no Comportamento de Cache
Esse é sutil e vai te pegar em produção se não prestar atenção.
De volta em Next.js 14, fetch() dentro de Server Components era cacheado agressivamente por padrão. Você tinha que fazer opt-out com { cache: 'no-store' }. Na Next.js 15 inverteram isso (fetch é uncached por padrão), e Next.js 16 continua nessa direção com alguns controles mais explícitos.
Se você migrou de 14 pra 16 em um pulo (como fiz com um dos meus sites), suas páginas que dependiam do comportamento de cache padrão antigo vão começar a fazer fetches ao vivo em cada request. Para algumas páginas, tudo bem. Para outras, vai bombardear sua API e afundar seus tempos de resposta.
The fix is explicit: use export const revalidate = 3600 (or whatever interval makes sense) at the route segment level, or pass { next: { revalidate: 3600 } } directly in your fetch call. The Next.js caching documentation has a solid breakdown of what caches what and when.
Auditei cada rota de data-fetching no site afetado usando um grep rápido por fetch( e adicionei declarações explícitas de cache. Tomou umas duas horas mas valeu, tempos de resposta caíram de ~800ms de média pra ~120ms depois do fix.
---
Turbopack na Prática: O Bom e o Chato
Vou ser reto com você: Turbopack é impressionante. Cold start times são dramaticamente melhores. Hot module replacement se sente quase instantâneo na maioria das mudanças. Pro desenvolvimento do dia a dia é um upgrade de qualidade de vida significativo.
Mas tem arestas ásperas.
O que ainda não funciona
Na época que fiz essas migrações, um punhado de coisas ainda não era totalmente suportado no Turbopack para dev:
- Alguns loaders específicos do Webpack ainda não têm equivalente no Turbopack. SVGR precisou de uma mudança de configuração (a sintaxe das regras do Turbopack é diferente da module.
rulesdo Webpack). - Transforms customizadas do Babel. Turbopack usa apenas SWC. Se seu projeto tem um
.babelrcoubabel.config.jscom plugins customizados, eles não serão executados. Essa é uma limitação conhecida e a equipe do Vercel é transparente sobre isso na documentação do Turbopack. - Algumas combinações de plugins PostCSS se comportam de forma inesperada em dev. Vi isso em uma setup Tailwind v4 + PostCSS customizado, a solução foi fixar a ordem dos plugins PostCSS explicitamente.
O sinalizador `--turbopack` agora é desnecessário
Como Turbopack é o padrão para next dev na versão 16, você não precisa mais do sinalizador --turbopack. Se você o tem em seus scripts do package.json por ter experimentado na versão 15, não vai prejudicar nada, mas é redundante. Limpe seus scripts.
---
Atualizações de TypeScript e Configuração ESLint
Duas coisas de manutenção que me confundiram.
Next.js 16 passou a exigir TypeScript 5.x. Se você ainda está no TypeScript 4.x (e alguns projetos antigos estão), precisa atualizar isso separadamente. Execute npx tsc --version antes de começar qualquer outra coisa.
A história da configuração ESLint também mudou. Next.js 16 vem com suporte a ESLint 9, e ESLint 9 usa um formato de configuração flat (eslint.config.js) em vez do formato antigo .eslintrc. Se você ainda está no formato antigo, Next.js fará fallback gracefully, mas você verá um aviso. Migrei dois dos meus projetos para a flat config enquanto estava lá. Honestamente é mais limpo depois que você supera o atrito inicial.
---
Meu Checklist de Migração (Em Ordem)
Isso é o que eu entregaria para qualquer um do meu time fazendo esse upgrade:
- Faça backup dos seus arquivos de configuração atuais e do lock file antes de mexer em qualquer coisa
- Verifique a versão do seu Node.js, Next.js 16 requer Node 18.18 ou mais recente
- Execute
npx @next/codemod@latest upgradena versão atual primeiro - Atualize as versões de next, react,
react-domnopackage.jsone instale - Revise
next.config.jspara flagsexperimentalpromovidas ou removidas - Execute
npm ls reactpara detectar conflitos de bibliotecas de terceiros - Procure no seu codebase por
fetch(e audite as declarações de cache - Verifique se há algum
.babelrcou loaders específicos do Webpack que precisem de equivalentes Turbopack - Inicie o dev, leia todos os avisos antes de mexer em componentes
- Execute um build de produção localmente (
next build) antes de fazer deploy em qualquer lugar - Faça deploy em um ambiente de staging e execute um teste manual completo
Esse último passo parece óbvio. Mas já vi pessoas pular staging e fazer push direto para produção em upgrades "pequenos". Uma mudança de comportamento de cache que faz sua homepage bater em uma API live a cada requisição não é uma coisa pequena.
---
FAQ
Next.js 16 é estável o suficiente para produção?
Sim, para a maioria dos casos de uso. A mudança Turbopack-for-dev é o maior deslocamento, e como as compilações de produção ainda usam Webpack, seu resultado realmente implantado é menos afetado do que sua experiência de desenvolvimento. As mudanças de comportamento de cache são a maior preocupação de produção, e são diretas de auditar se você for metódico a respeito.
Preciso fazer upgrade do React para 19 ao mesmo tempo?
Tecnicamente Next.js 16 suporta React 18 como mínimo, mas os novos recursos (como o hook use() estável e a mudança de ref-as-prop) exigem React 19. Se você estiver em um projeto com muitas dependências de terceiros, vale a pena verificar a compatibilidade antes de se comprometer com React 19 ao mesmo tempo. O guia de upgrade do React 19 vale a pena ser lido junto com a documentação de migração do Next.js.
Minha configuração customizada do Webpack desapareceu sob Turbopack. O que eu faço?
Sua configuração do Webpack ainda é executada durante next build. Para dev, você precisa replicar as partes relevantes usando a chave turbopack em next.config.js. A sintaxe é diferente, especialmente para transformações de arquivo e aliases. Confira a referência oficial de configuração do Turbopack e espere gastar uma ou duas horas nisso se sua configuração do Webpack for complexa.
Quão mais rápido é o Turbopack na verdade?
Nos projetos que testei: cold start caiu de 12-18 segundos para 3-4 segundos. HMR em mudanças de componentes foi de 1-3 segundos para menos de 200ms na maioria dos casos. Estes são números aproximados e variarão com o tamanho do projeto, mas a diferença é perceptível em qualquer coisa além de um projeto trivial.
---
O upgrade vale a pena fazer. A velocidade de dev do Turbopack sozinha muda como você se sente ao trabalhar em uma base de código grande Next.js. Apenas vá com os olhos abertos sobre as mudanças de cache e os verificações de compatibilidade de biblioteca de terceiros, essas duas coisas são onde a maioria do tempo realmente vai.
Faça um site por vez. Eu fiz.
