Seu pipeline de CI termina um build do Next.js e envia para Vercel. Quatro minutos depois, seu deploy em preview fica pronto. Você aceitou esse ritmo porque o Webpack sempre foi lento em escala — até o Turbopack se tornar o bundler padrão no Next.js 16. Migramos três apps de clientes fora do Next.js 15 em março de 2025, buscando aqueles tempos de build abaixo de um minuto que as notas de lançamento prometiam. Dois deploys quebraram imediatamente. Uma integração do Sentry parou de reportar. Um plugin custom do Webpack que usávamos há dois anos não tinha equivalente no Turbopack. Mas os apps que sobreviveram? Os tempos de build caíram de 3m 52s para 51 segundos, e um bundle particularmente complicado encolheu 18%. Aqui está cada mudança que documentamos, os deltas de performance que medimos, e a sequência de migração que nos permitiu fazer o deploy sem rollback.

Isso não é uma reiteração das notas de lançamento. Isso é o que realmente aconteceu quando executamos next build com Turbopack em codebases reais com complexidade real.

Índice

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

Por que Next.js 16 é uma Grande Mudança

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 migrou de pages para o App Router. O recurso de destaque é óbvio: o Turbopack substitui o 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 versão mínima suportada — sem mais compatibilidade com React 18
  • Streaming melhorado e maturidade de prerendering parcial
  • Novos padrões de cache que fazem sentido (aprenderam com o protesto de cache do Next.js 15)
  • APIs de request assíncronas totalmente aplicadascookies(), headers() e params agora são assincronos sem suporte legado síncrono
  • Requisito mínimo de Node.js 20 — suporte para Node 18 desapareceu

Para agências como a nossa fazendo desenvolvimento Next.js, esse é o tipo de lançamento que toca tudo. Você não pode apenas bumpar o número da versão e chamar de pronto.

O Que Realmente Mudou com Turbopack em Produção

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

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

Arquitetura de Compilação Incremental

O Webpack processa seu gráfico de dependências inteiro em cada build. O Turbopack usa um sistema de cache de nível funcional construído no engine 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 o segundo, terceiro e décimo builds serão.

Melhorias de Tree Shaking

O tree shaking do Turbopack opera em um nível mais granular do que o do webpack. Notamos que nossos bundles de cliente eram 8-15% menores em média através de nossos três projetos sem nenhuma mudança de código. As maiores vitórias vieram do tratamento de barrel files — o Turbopack é genuinamente melhor em eliminar re-exports não utilizadas de arquivos index.

Resolução de Módulo

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

Estratégia de Code Splitting

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

SWC Agora é Obrigatório

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

Benchmarks de Performance do Build

Aqui estão números reais de nossos três projetos de migração. Esses não são benchmarks sintéticos — são de aplicações reais de clientes rodando em nosso pipeline de CI no GitHub Actions (Ubuntu, runners com 4 vCPU, 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
Bundle size change -12% -8% -14%
JS First Load (homepage) -18KB -7KB -22KB
Build memory peak 3.8GB → 2.9GB 1.6GB → 1.2GB 4.2GB → 3.1GB

Os números de warm cache são a verdadeira história. Uma vez que o 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 estaticamente geradas), ir de 6+ minutos para menos de 2 minutos em builds cached foi significativo. Isso é dinheiro real economizado em minutos de CI.

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

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

Mudanças Significativas que Você Precisa Conhecer

Aqui está uma lista em andamento de tudo que realmente quebrou durante nossas migrações. O guia de upgrade do Next.js 16 cobre alguns desses, mas alguns nos pegaram de surpresa.

1. Configuração Custom do Webpack

Essa é a grande. Se você tiver uma chave webpack em seu next.config.js, não funciona mais. O Turbopack tem sua própria API de configuração sob turbopack no config 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 Request Síncronas Removidas

Next.js 15 descontinuou o acesso síncrono a cookies(), headers(), params e searchParams. Next.js 16 as remove inteiramente. Se você ignorou esses avisos de descontinuação, você vai ter um tempo ruim.

// ANTES — isso 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>;
}

Isso parece trivial, mas tocou mais de 200 componentes através de 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ê tiver dependências fixadas em React 18, elas precisam ser atualizadas. A maioria das bibliotecas bem mantidas tinha suporte para React 19 em meados de 2025, mas encontramos alguns retardatários.

4. Node.js 18 Descontinuado

O mínimo é Node.js 20. Atualize suas imagens Docker, configs de CI e arquivos .nvmrc.

5. Mudanças em next/image

A prop onLoadingComplete foi totalmente removida (foi descontinuada desde Next.js 14). Use onLoad no 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 no primeiro request.

Nosso Processo de Migração Passo a Passo

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

Passo 1: Audite Dependências

Antes de tocar no 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: nossa SDK de CMS headless, biblioteca de autenticação e biblioteca de componentes UI.

Passo 2: Atualize Node.js

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

Passo 3: Atualize React Primeiro

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

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

Passo 4: Execute 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

Isso tratou cerca de 70% das migrações de API assincronas automaticamente. Não é perfeito — teve dificuldade com alguns de nossos padrões mais complexos de componentes de servidor — mas nos economizou horas.

Passo 5: Atualize Next.js

npm install next@16

Passo 6: Migre next.config.js

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

Passo 7: Corrija 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 do que as do webpack na maioria dos casos — mais específicas, com caminhos de arquivo mais claros e sugestões.

Passo 8: Teste 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 ordem de CSS (o Turbopack processa imports de CSS em uma ordem ligeiramente diferente do webpack) e um import dinâmico que não estava fazendo code-split corretamente.

Passo 9: Validação de Performance

Comparamos scores de Lighthouse e Core Web Vitals antes e depois. Cada projeto melhorou ou ficou neutro. Sem regressões.

Traduções de Configuração Webpack

Esta seção é para times com configurações customizadas de webpack. 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

// Resolve aliases 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 da v16, mas o formato de output mudou
  • Custom chunk splitting via splitChunks — O Turbopack lida com isso 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 — Precisava da v9+ para compatibilidade com Turbopack. Versões anteriores se conectavam 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 limpo.

@vanilla-extract/next-plugin — Esse foi nosso maior incômodo no Projeto B. O plugin webpack do Vanilla Extract não tinha um equivalente Turbopack até sua release 2.0. Tivemos que esperar por isso ou considerar alternativas. Esperamos.

Pacotes de barrel files — Qualquer pacote que exporte centenas de componentes de um arquivo index único (olhando para você, bibliotecas de ícones) agora fica tree-shaken muito mais agressivamente. Isso é uma coisa boa, mas vimos um caso onde um ícone dinamicamente referenciado não estava sendo incluído. Mudamos de lookups baseados em string para imports diretos, que é melhor prática de qualquer forma.

Considerações de CSS e Tailwind

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

Ordem de Import de CSS

O Turbopack processa imports de CSS em uma ordem determinística mas diferente do 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á às vezes), 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 flipou.

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

CSS Modules

CSS Modules funcionam identicamente. Nenhuma mudança necessária. Os nomes de classe gerados parecem diferentes (mais curtos, realmente), mas isso é cosmético a menos que você esteja fazendo algo estranho como alvejar nomes de classe gerados em testes.

PostCSS

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

Atualizações de Deployment e Pipeline de CI

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

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

AWS/OpenNext: Exigiu atualizar para OpenNext 4.x, que adicionou suporte de output do Turbopack. O formato de output mudou ligeiramente — a estrutura do diretório .next foi reorganizada — então qualquer script pós-build que referenciasse caminhos de arquivo específicos precisava ser atualizado.

Docker builds: Se você está buildando 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 layer do Docker. Adicionamos um layer COPY específico para isso.

# Otimize caching de layer do 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

Não quero pintar isso como tudo rosas. Há razões legítimas para ficar no Next.js 15 por enquanto:

  • Dependência pesada de plugins webpack: Se seu build conta com 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 config webpack compartilhada: Se você está compartilhando config webpack através de 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 possa tolerar downtime.
  • Dependências legadas presas em React 18: Se uma dependência crítica não adicionou suporte para React 19, você está bloqueado independentemente.

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

FAQ

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

Sim. O Turbopack está em desenvolvimento por mais de três anos, foi teste em batalha em modo dev através de milhões de projetos Next.js, e passou por um beta estendido em builds de produção durante Next.js 15.3-15.5. Estamos rodando ele em produção desde o lançamento 16.0 através de múltiplos sites de clientes sem problemas relacionados a bundler. Dito isso, se você está na 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ê vai precisar ficar no Next.js 15, que receberá patches de segurança através do início de 2026. Vercel foi claro que o suporte a webpack no Next.js acabou.

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

Em builds cold (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 quantidade de geração estática acontecendo. Uso de memória também caiu 20-30% consistentemente através de nossos projetos.

Preciso reescrever meu next.config.js para Turbopack?

Se você tiver configuração customizada de webpack 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 padrão do Next.js (imagens, redirects, rewrites, variáveis de ambiente), essas funcionam exatamente igual. 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?

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

O Turbopack suporta todos os mesmos recursos do webpack no 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 customizada de webpack, há cerca de 90% de paridade de recursos. Os gaps restantes são principalmente em torno de plugins webpack de nicho e estratégias de chunk splitting altamente customizadas. Verifique os docs de compatibilidade do 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á buildando aplicações altamente interativas com gerenciamento complexo de estado, Next.js 16 é uma escolha forte e as melhorias do Turbopack tornam o DX significativamente melhor. Se você está buildando sites pesados em conteúdo com interatividade mínima, Astro continua sendo uma alternativa excelente com seu modelo de hidratação parcial. Estamos buildando com ambos e escolhendo baseado em requisitos do projeto. Se você está inseguro, nos contate e podemos ajudar você a avaliar.

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

Para uma aplicação típica de tamanho médio (50-200 rotas, dependências padrão, config webpack minimal customizado), budget 2-4 dias de tempo de desenvolvedor. Isso inclui atualizações de dependências, migrações de API assincronas, testes e verificação de deployment. Se você tiver config webpack extenso customizado ou dependências legadas, pode levar uma semana ou mais. Nosso time na Social Animal oferece serviços de migração se você preferir não queimar o sprint de seu time em trabalho de infraestrutura.