Estávamos acompanhando a maturação do Turbopack desde seu anúncio em 2022, executando-o em modo dev desde Next.js 14, e observando cautelosamente aquelas flags "turbo" em CI. Quando Next.js 16 chegou no início de 2025 com Turbopack como bundler padrão de produção, soubemos que a migração não podia esperar mais. Tínhamos três projetos de clientes no Next.js 15 que precisavam de upgrade, e vou orientá-lo através de cada mudança significativa, os problemas que enfrentamos, e os números de desempenho que vimos do outro lado.

Isto não é um resumo das notas de lançamento. Isto é o que realmente aconteceu quando executamos next build com Turbopack em bases de código reais com complexidade real.

Índice

Next.js 16 Turbopack Production Builds: O Que Mudou e Como Migramos

Por que Next.js 16 é um Grande Negócio

Next.js 16 não é apenas um bump de versão. Representa a mudança mais significativa na infraestrutura de build desde que o framework se moveu do Pages para o App Router. O recurso destaque é óbvio: Turbopack substitui webpack como o bundler padrão para builds de desenvolvimento e produção.

Mas há mais acontecendo. Next.js 16 também vem com:

  • React 19 como a versão mínima suportada — sem mais compatibilidade com React 18
  • Maturidade melhorada em streaming e prerendering parcial
  • Novos padrões de caching que são realmente sensatos (aprenderam com o reação ao caching do Next.js 15)
  • APIs de requisição assíncrona totalmente ativadascookies(), headers() e params são todos assíncronos agora, sem suporte síncrono legado
  • Requisito mínimo Node.js 20 — suporte a Node 18 foi eliminado

Para agências como a nossa fazendo desenvolvimento Next.js, este é o tipo de lançamento que toca tudo. Você não pode apenas atualizar um número de versão e dar por encerrado.

O Que Realmente Mudou com Turbopack em Produção

Vamos ser específicos. Durante Next.js 14 e 15, Turbopack estava disponível para next dev com a flag --turbo. Builds de produção ainda usavam webpack. Next.js 15.3 introduziu uma flag experimental --turbopack para next build, e quando 16 chegou, tornou-se o padrão.

Aqui está o que é fundamentalmente diferente sobre como Turbopack lida com builds de produção comparado ao webpack:

Arquitetura de Compilação Incremental

Webpack processa seu gráfico de dependência inteiro a cada build. Turbopack usa um sistema de caching em nível de função construído no motor Turbo (escrito em Rust). Na prática, isso significa que builds subsequentes apenas recompilam o que realmente mudou. Seu primeiro build pode não ser dramaticamente mais rápido, mas seu segundo, terceiro e décimo builds serão.

Melhorias em Tree Shaking

O tree shaking do Turbopack opera em um nível mais granular do que o do webpack. Notamos que nossas bundas de clientes eram 8-15% menores em média entre nossos três projetos sem mudanças de código. Os maiores ganhos vieram do tratamento de barrel files — Turbopack é genuinamente melhor em eliminar re-exportações não utilizadas de arquivos de índice.

Resolução de Módulo

Turbopack resolve módulos diferentemente. É mais rápido, mas também é mais rigoroso. Se você tinha algum caminho de import desleixado que webpack estava silenciosamente resolvendo (como extensões de arquivo faltando em certos casos extremos, ou caminhos insensíveis a maiúsculas em macOS que quebram no Linux), Turbopack vai pegar. Isto causou cerca de 30% dos nossos problemas de migração.

Estratégia de Code Splitting

O algoritmo de code splitting é novo. Turbopack cria mais, chunks menores por padrão. Isto geralmente melhora o desempenho de carregamento para navegadores modernos com HTTP/2, mas pode aumentar o número total de requisições. Vimos contagens de chunks aumentarem cerca de 40% enquanto o tamanho total do bundle diminuía.

SWC Agora é Obrigatório

Se você ainda estava agarrado em qualquer configuração Babel, desapareceu. Turbopack usa exclusivamente SWC para transformação. Isto já era a direção em que as coisas estavam indo, mas Next.js 16 remove qualquer fallback para Babel completamente.

Benchmarks de Desempenho de Build

Aqui estão números reais de nossos três projetos de migração. Estes não são benchmarks sintéticos — são de aplicações de clientes reais em execução em nosso pipeline de CI no GitHub Actions (Ubuntu, 4 vCPU, runners com 16GB RAM).

Métrica Projeto A (E-commerce) Projeto B (SaaS Dashboard) Projeto C (Site de Conteúdo)
Páginas/Rotas 847 124 2.340
webpack build (Next 15) 4m 32s 1m 48s 6m 15s
Turbopack build (Next 16, cold) 3m 10s 1m 22s 4m 44s
Turbopack build (Next 16, warm cache) 1m 05s 28s 1m 52s
Mudança de tamanho do bundle -12% -8% -14%
JS First Load (homepage) -18KB -7KB -22KB
Peak de memória de build 3.8GB → 2.9GB 1.6GB → 1.2GB 4.2GB → 3.1GB

Os números do warm cache são a história real. Uma vez que Turbopack construiu seu projeto uma vez, rebuilds incrementais são dramaticamente mais rápidos. Para nosso Projeto C pesado em conteúdo (que usa um CMS headless com milhares de páginas geradas estaticamente), ir de 6+ minutos para menos de 2 minutos em builds em cache foi significativo. Isso é dinheiro real economizado em minutos de CI.

Melhorias de uso de memória também foram significativas. Projeto A ocasionalmente atingia erros de OOM em runners de CI menores com webpack. Esse problema desapareceu com Turbopack.

Next.js 16 Turbopack Production Builds: O Que Mudou e Como Migramos - arquitetura

Mudanças Quebradas que Você Precisa Conhecer

Aqui está uma lista executiva de tudo o que realmente quebrou durante nossas migrações. O guia de upgrade do Next.js 16 cobre alguns destes, mas alguns nos pegaram desprevenidos.

1. Configuração Webpack Customizada

Este é o grande. Se você tem uma chave webpack em seu next.config.js, não funciona mais. Turbopack tem sua própria API de configuração sob turbopack na configuração do Next.js. Nem tudo tem um mapeamento 1:1.

// next.config.js — ANTES (Next.js 15 com webpack)
module.exports = {
  webpack: (config) => {
    config.module.rules.push({
      test: /\.svg$/,
      use: ['@svgr/webpack'],
    });
    return config;
  },
};
// next.config.js — DEPOIS (Next.js 16 com Turbopack)
module.exports = {
  turbopack: {
    rules: {
      '*.svg': {
        loaders: ['@svgr/webpack'],
        as: '*.js',
      },
    },
  },
};

2. APIs de Requisição Síncronas Removidas

Next.js 15 deprecou acesso síncrono a cookies(), headers(), params e searchParams. Next.js 16 os remove completamente. Se você ignorou aqueles avisos de depreciação, vai ter um mau tempo.

// ANTES — isto quebra em Next.js 16
export default function Page({ params }) {
  const { slug } = params;
  return <div>{slug}</div>;
}

// DEPOIS
export default async function Page({ params }) {
  const { slug } = await params;
  return <div>{slug}</div>;
}

Isto parece trivial mas tocou mais de 200 componentes entre nossos projetos. Escrevemos um codemod para lidar com a maioria (mais sobre isso abaixo).

3. React 18 Não Mais Suportado

Next.js 16 requer React 19. Se você tem dependências fixadas em React 18, precisam de atualização. A maioria das bibliotecas bem mantidas tinha suporte a React 19 até meados de 2025, mas encontramos um casal de retardatários.

4. Node.js 18 Descontinuado

Mínimo é Node.js 20. Atualize suas imagens Docker, configurações de CI e arquivos .nvmrc.

5. Mudanças em next/image

A prop onLoadingComplete é totalmente removida (foi deprecada desde Next.js 14). Use onLoad em seu lugar. O pipeline de otimização de imagem também usa uma nova biblioteca subjacente, o que significa que suas imagens otimizadas em cache serão regeneradas na primeira requisição.

Nosso Processo de Migração Passo a Passo

Aqui está o processo real que seguimos. Fizemos Projeto B (o menor) primeiro como um teste, depois abordamos A e C.

Passo 1: Auditar Dependências

Antes de tocar em Next.js, auditamos cada dependência para compatibilidade com React 19 e Node.js 20. Usamos um script simples:

npx npm-check-updates --target latest --filter '/react|next/'

Também verificamos manualmente nossos pacotes mais críticos: nosso SDK de CMS headless, biblioteca de autenticação e biblioteca de componentes de UI.

Passo 2: Atualizar Node.js

Atualizamos nosso .nvmrc para 20.18.0 (último LTS na época), atualizamos Dockerfiles e verificamos runners de CI. Simples mas fácil de esquecer.

Passo 3: Atualizar React Primeiro

npm install react@19 react-dom@19 @types/react@19 @types/react-dom@19

Executamos a suite completa de testes aqui antes de prosseguir. React 19 tem seus próprias mudanças quebradas (removeu forwardRef como necessidade, ref agora é uma prop regular, hook use() é estável). Corrigimos aqueles problemas isoladamente para não estarmos debugando problemas de React e Next.js simultaneamente.

Passo 4: Executar o Codemod do Next.js

Next.js fornece um codemod de upgrade que lida com muitas das mudanças mecânicas:

npx @next/codemod@latest upgrade

Isto lidou com cerca de 70% das migrações de API assíncrona automaticamente. Não é perfeito — teve dificuldade com alguns dos nossos padrões de componente servidor mais complexos — mas nos economizou horas.

Passo 5: Atualizar Next.js

npm install next@16

Passo 6: Migrar next.config.js

Este foi o passo mais demorado para Projeto A, que tinha customização webpack significativa. Vou cobrir as traduções específicas na próxima seção.

Passo 7: Corrigir Erros de Build Iterativamente

Executamos next build e trabalhamos através de erros um por um. As mensagens de erro do Turbopack são realmente melhores que as do webpack na maioria dos casos — mais específicas, com caminhos de arquivo mais claros e sugestões.

Passo 8: Testes de Regressão Visual

Usamos Playwright para testes E2E e executamos nossa suite de regressão visual para pegar qualquer diferença de renderização. Encontramos dois problemas: uma diferença de ordenação CSS (Turbopack processa importações de CSS em uma ordem ligeiramente diferente que webpack) e um import dinâmico que não estava fazendo code splitting corretamente.

Passo 9: Validação de Desempenho

Comparamos scores do Lighthouse e Core Web Vitals antes e depois. Todo projeto melhorou ou permaneceu neutro. Sem regressões.

Traduções de Configuração Webpack

Esta seção é para equipes com configurações webpack customizadas. Aqui está como padrões comuns se traduzem para Turbopack.

Loaders Customizados

// Equivalente Turbopack para loaders customizados
module.exports = {
  turbopack: {
    rules: {
      '*.md': {
        loaders: ['raw-loader'],
        as: '*.js',
      },
      '*.graphql': {
        loaders: ['graphql-tag/loader'],
        as: '*.js',
      },
    },
  },
};

Aliases de Módulo

// Aliases de resolução funcionam similarmente
module.exports = {
  turbopack: {
    resolveAlias: {
      'old-package': 'new-package',
      // Você também pode apontar para arquivos locais
      '@legacy/utils': './src/utils/legacy.ts',
    },
  },
};

O Que Não Se Traduz

Alguns plugins webpack simplesmente não têm equivalentes Turbopack ainda:

  • webpack.DefinePlugin — Use env em next.config.js ou variáveis de ambiente diretamente
  • BundleAnalyzerPlugin — O pacote @next/bundle-analyzer funciona com Turbopack a partir de v16, mas o formato de saída mudou
  • Custom chunk splitting via splitChunks — Turbopack lida com isto automaticamente e não expõe o mesmo nível de controle. Honestamente, os padrões são bons o suficiente para a maioria dos projetos.
  • webpack.IgnorePlugin — Use resolveAlias para apontar imports para módulos vazios

Lidando com Pacotes de Terceiros

Alguns pacotes causaram problemas durante a migração:

@sentry/nextjs — Necessitava v9+ para compatibilidade com Turbopack. Versões anteriores se enganchavam em internals do webpack. A atualização foi direta mas exigiu mudanças de config.

next-intl — Funcionou bem após atualizar para a versão mais recente. A API do plugin se adaptou limpamente.

@vanilla-extract/next-plugin — Este foi nosso maior dor de cabeça no Projeto B. O plugin webpack do Vanilla Extract não tinha um equivalente Turbopack até sua versão 2.0. Tivemos que esperar por isso ou considerar alternativas. Nós esperamos.

Pacotes de barrel file — Qualquer pacote que exporta centenas de componentes de um único arquivo de índice (olhando para você, bibliotecas de ícone) agora recebe tree-shaking muito mais agressivamente. Isto é uma coisa boa, mas vimos um caso onde um ícone dinamicamente referenciado não estava sendo incluído. Mudamos de lookups de ícones baseados em string para imports diretos, o que é melhor prática mesmo assim.

Considerações sobre CSS e Tailwind

Se você está usando Tailwind CSS (e a maioria dos nossos projetos está), a migração é principalmente indolor. Tailwind v4 funciona ótimo com Turbopack. Mas há algumas coisas para ficar atento:

Ordenação de Import CSS

Turbopack processa importações de CSS em uma ordem determinística mas diferente que webpack. Se você está contando com ordem de import para especificidade (e você não deveria estar, mas vamos ser honestos — todos nós acabamos lá em algum momento), você pode ver diferenças visuais. Tivemos um projeto onde um reset global estava sendo sobrescrito por um CSS module de componente porque a ordem de import virou.

O fix foi uso explícito de @layer em nosso CSS, o qual deveríamos estar fazendo o tempo todo.

CSS Modules

CSS Modules funcionam identicamente. Nenhuma mudança necessária. Os nomes de classes gerados parecem diferentes (mais curtos, na verdade), mas isto é cosmérico a menos que você esteja fazendo algo esquisito como alvejar nomes de classes gerados em testes.

PostCSS

Arquivos de configuração PostCSS ainda são respeitados. Seu postcss.config.js continua a funcionar. Nenhuma mudança necessária aqui.

Atualizações de Pipeline de Implantação e CI

Nossos alvos de implantação são primariamente Vercel e AWS (via SST/OpenNext). Aqui está o que mudou:

Vercel: Automaticamente detectou Next.js 16 e usou Turbopack. Integração de cache de build funciona fora da caixa. Nossos tempos de build em Vercel caíram ainda mais dramaticamente que CI local porque Vercel tem integração profunda com a camada de caching do Turbopack. Projeto C foi de ~8 minutos para ~2.5 minutos em Vercel.

AWS/OpenNext: Exigiu atualização para OpenNext 4.x, que adicionou suporte de saída Turbopack. O formato de saída mudou ligeiramente — a estrutura do diretório .next é reorganizada — então qualquer script pós-build que referenciava caminhos de arquivo específicos necessitava de atualização.

Builds Docker: Se você está construindo Next.js em Docker, atualize sua imagem base para Node 20+ e esteja ciente de que o diretório de cache do Turbopack (.next/cache/turbopack) deve ser incluído em sua estratégia de caching de camada Docker. Adicionamos uma camada COPY específica para isto.

# Otimize caching de camada Docker para Turbopack
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
# Cache mount para Turbopack
RUN --mount=type=cache,target=/app/.next/cache \
    npm run build

Quando Você NÃO Deve Migrar Ainda

Eu não quero pintar isto como tudo flores. Há razões legítimas para ficar no Next.js 15 por enquanto:

  • Dependência pesada de plugin webpack: Se seu build depende de 3+ plugins webpack customizados que não têm equivalentes Turbopack, o custo de migração pode não valer a pena ainda.
  • Monorepo com configuração webpack compartilhada: Se você está compartilhando config webpack entre projetos Next.js e não-Next.js em um monorepo, dividir essa config é trabalho adicional.
  • Requisitos de estabilidade: Next.js 16.0 é estável, mas 16.1 e 16.2 corrigiram bugs reais. Eu esperaria por pelo menos 16.2+ antes de migrar qualquer coisa que você não pode tolerar downtime.
  • Dependências legadas presas em React 18: Se uma dependência crítica não adicionou suporte a React 19, você está bloqueado independentemente.

Para equipes fazendo desenvolvimento de CMS headless, a migração é geralmente mais suave porque sites acionados por CMS tendem a ter configurações de build mais simples.

FAQ

Turbopack é estável o suficiente para produção em Next.js 16?

Sim. Turbopack tem estado em desenvolvimento por mais de três anos, foi testado em combate em modo dev através de milhões de projetos Next.js, e foi através de um beta estendido em builds de produção durante Next.js 15.3-15.5. Temos estado executando isso em produção desde a versão 16.0 através de múltiplos sites de clientes sem problemas relacionados a bundler. Dito isto, se você está em 16.0 especificamente, atualize para 16.2+ onde vários bugs de caso extremo foram resolvidos.

Posso ainda usar webpack com Next.js 16?

Não como o bundler primário, não. Turbopack é o único bundler suportado em Next.js 16. Se você absolutamente precisa de webpack, você precisará ficar no Next.js 15, que receberá patches de segurança até início de 2026. Vercel foi claro que suporte a webpack em Next.js é feito.

Quão mais rápido é Turbopack comparado a webpack para builds de produção?

Em builds frios (sem cache), vimos melhorias de 20-30%. Em builds warm/cached, a melhoria salta para 50-70%. Os números exatos dependem muito do tamanho do projeto, número de rotas e a quantidade de geração estática acontecendo. Uso de memória também caiu 20-30% consistentemente entre nossos projetos.

Preciso reescrever meu next.config.js para Turbopack?

Se você tem configuração webpack customizada em seu next.config.js, sim — esses blocos precisam ser traduzidos para o formato de configuração turbopack. Se você está apenas usando opções de config Next.js padrão (imagens, redirects, rewrites, variáveis de env), aqueles todos funcionam exatamente do mesmo jeito. O esforço de migração é proporcional a quanto config webpack customizado você tem.

Meu pipeline de CI/CD existente funcionará com Next.js 16?

Principalmente sim. As principais coisas para atualizar são: versão do Node.js (mínimo 20), qualquer script que referencie arquivos de saída específicos de webpack, e qualquer estratégia de caching que alvo .next/cache/webpack. Você vai querer cachear .next/cache/turbopack em seu lugar. Se você está deployando para Vercel, tudo é tratado automaticamente.

Turbopack suporta todos os mesmos recursos que webpack em Next.js?

Para recursos específicos do Next.js, sim — App Router, Pages Router, rotas de API, middleware, ISR, SSG, SSR todos funcionam. Para configuração webpack customizada, há cerca de 90% de paridade de recurso. As lacunas restantes são principalmente em torno de plugins webpack de nicho e estratégias de chunk splitting altamente customizadas. Verifique a documentação de compatibilidade Turbopack para seu caso de uso específico.

Devo migrar para Next.js 16 ou considerar alternativas como Astro?

Depende do seu caso de uso. Se você está construindo aplicações altamente interativas com gerenciamento de estado complexo, Next.js 16 é uma escolha forte e as melhorias do Turbopack fazem a DX significativamente melhor. Se você está construindo sites ricos em conteúdo com interatividade mínima, Astro permanece uma alternativa excelente com seu modelo de hidratação parcial. Temos estado construindo com ambos e escolhendo baseado em requisitos de projeto. Se você está inseguro, nos contacte e podemos ajudá-lo a avaliar.

Qual é o tempo mínimo necessário para migrar um app Next.js 15 de tamanho médio para 16?

Para uma aplicação típica de tamanho médio (50-200 rotas, dependências padrão, configuração webpack mínima customizada), orce 2-4 dias de tempo de desenvolvedor. Isto inclui atualizações de dependência, migrações de API assíncrona, testes e verificação de deployment. Se você tem configuração webpack extensa customizada ou dependências legadas, poderia levar uma semana ou mais. Nosso time na Social Animal oferece serviços de migração se você preferir não queimar o sprint do seu time em trabalho de infraestrutura.