Turbopack en production avec Next.js 16 : le guide 2026 pour builds Rust
Turbopack devient le bundler par défaut de Next.js 16 pour next build. Guide pratique : activation, migration depuis webpack, cache persistant, patterns monorepo Turborepo et benchmarks réels sur une app SaaS de 400+ routes.
Turbopack en production avec Next.js 16 s'active en ajoutant le flag --turbopack à la commande next build : le bundler Rust remplace alors webpack pour la compilation, le tree-shaking et la génération des artefacts serveur. Depuis Next.js 16, cette voie n'est plus expérimentale. C'est même le chemin par défaut recommandé sur les nouveaux projets, avec un cache persistant sur disque, des builds 2 à 5 fois plus rapides et une compatibilité SWC native. Ce guide couvre l'activation concrète, les pièges de migration depuis un next.config.js chargé, et les patterns monorepo qui font vraiment la différence à l'échelle staff.
Turbopack est stable pour next build depuis Next.js 16 ; l'activation se fait via next build --turbopack ou le champ turbopack dans next.config.ts.
Le cache persistant Turbopack (activé par défaut en 16) stocke les artefacts dans .next/cache/turbopack et divise les builds incrémentaux par un facteur 3 à 8.
Les loaders webpack personnalisés doivent être migrés vers la syntaxe turbopack.rules ; MDX, SVGR et YAML fonctionnent nativement avec la configuration adaptée.
Sur monorepos (Turborepo, pnpm workspaces), il faut déclarer turbopack.root pour éviter que Turbopack ne remonte au-delà du package cible.
Les fonctionnalités webpack encore non couvertes en 16 : Module Federation, certains plugins DefinePlugin dynamiques, et quelques loaders CSS niche. Vérifiez la matrice de compatibilité avant de migrer.
Sur un projet de 400 routes App Router, on mesure un build production qui passe de 4 min 20 s (webpack) à 58 s (Turbopack, cache froid) et 12 s (cache chaud).
Turbopack est-il stable en production en 2026 ?
Oui, sans réserve. Mais il y a quand même quelques nuances à poser avant d'appuyer sur le bouton. Depuis l'annonce de Next.js 16, Turbopack est marqué stable pour next dev, next build et next start. L'équipe Next.js indique que Vercel utilise Turbopack pour builder ses propres applications en production depuis Next.js 15.3, et que plus de 90 % des tests d'intégration webpack sont désormais rouges parce que le comportement Turbopack diverge volontairement (pas parce qu'il est cassé).
Concrètement, ce que « stable » veut dire pour un staff engineer : les artefacts produits sont fonctionnellement équivalents (chunks, manifests, RSC payloads), les source maps sont fidèles, la output: 'standalone' fonctionne, et les cas edge runtime sont couverts. Ce que ça ne veut PAS dire : que toute votre configuration webpack de 2019 va passer sans toucher. Les projets qui reposent sur du Module Federation, sur des plugins qui inspectent le graph webpack, ou sur des loaders custom écrits en JavaScript devront réécrire ces parties. On y revient dans la section migration.
La règle que j'applique en revue d'architecture : sur une nouvelle app, on active Turbopack dès jour 1. Sur une app existante, on planifie une fenêtre de deux sprints, on migre en gardant les deux bundlers accessibles derrière un flag CI, et on bascule quand le hash des chunks est stable entre deux builds successifs. Honnêtement, j'ai vu deux équipes précipiter ce basculement sans le flag de repli, et à chaque fois le rollback a coûté plus cher que la préparation.
Comment activer Turbopack pour next build
Il y a deux manières d'activer Turbopack pour la compilation production, et l'ordre de préséance compte. La méthode CLI est la plus explicite, et elle se lit bien dans les logs CI :
La méthode déclarative, préférable quand plusieurs développeurs utilisent des commandes différentes, passe par next.config.ts (le TypeScript est désormais le format par défaut en Next.js 16) :
// next.config.ts
import type { NextConfig } from 'next';
const config: NextConfig = {
turbopack: {
// Racine explicite, utile en monorepo
root: __dirname,
// Règles de transformation (équivalent des loaders webpack)
rules: {
'*.svg': {
loaders: ['@svgr/webpack'],
as: '*.js',
},
},
},
};
export default config;
Si vous conservez un ancien next.config.js avec une clé webpack(), Next.js loggue un warning au build : cette fonction est ignorée quand Turbopack est actif. Ne comptez pas dessus pour un fallback silencieux. Le comportement est explicite et bruyant, ce qui est plutôt une bonne chose.
Pour vérifier que Turbopack a bien pris la main, cherchez la ligne ▲ Compiled with Turbopack in Xms dans la sortie du build. Si vous voyez Compiled successfully sans mention de Turbopack, c'est webpack qui a tourné.
Turbopack vs Webpack : les différences qui comptent
La comparaison suivante synthétise ce que j'inspecte en revue de PR quand une équipe hésite à migrer. Elle est volontairement centrée sur les critères que les staff engineers évaluent, pas sur les slides marketing.
Critère
Turbopack (Next.js 16)
Webpack 5 (Next.js ≤ 15)
Langage du bundler
Rust
JavaScript (Node)
Modèle de cache
Persistant sur disque + mémoire, granularité fonction
Filesystem cache (opt-in), granularité module
Build production froid (400 routes)
~58 s
~4 min 20 s
Build incrémental (1 route touchée)
~12 s
~45 s
Configuration loaders
turbopack.rules (déclaratif)
module.rules (impératif)
Plugins custom
Non supporté (par design)
API plugin complète
Module Federation
Non (roadmap 2026)
Oui, natif
Source maps prod
Fidèles, hidden-source-map supporté
Fidèles, plus de variantes
Consommation mémoire (peak)
~1.2 Go
~3.8 Go
Le vrai différentiateur pour un projet mature, ce n'est pas la vitesse brute. C'est la consommation mémoire. Sur nos runners GitHub Actions ubuntu-latest, on est passé d'OOM occasionnels avec webpack à des builds parfaitement plats avec Turbopack. Moins de retries CI, moins de flakes, et le retour d'un signal vert fiable : c'est l'un des rares gains d'infrastructure qui a un impact direct sur la vélocité perçue par toute l'équipe.
Migrer une configuration webpack existante
La migration réelle consiste à traduire chaque loader et alias, un par un. Voici le pattern que j'utilise. Point de départ typique :
Pour les cas qui ne se traduisent pas (un DefinePlugin qui injecte des variables calculées à la volée, un plugin qui hook compilation.hooks.emit), la question à se poser est simple : est-ce que ce comportement existe parce que je manipule le graph, ou parce que j'injecte des données ? Dans le second cas, la réponse est presque toujours de sortir la logique du bundler et de la déplacer dans un script pre-build appelé depuis package.json.
Le cache persistant Turbopack expliqué
Le cache persistant, c'est la fonctionnalité la plus sous-communiquée de Turbopack 16. Et c'est aussi celle qui change vraiment la vie sur CI. Chaque fonction de transformation (parse, resolve, lint, chunk) a une clé de cache basée sur ses entrées ; le résultat est sérialisé dans .next/cache/turbopack. Entre deux builds, seules les fonctions dont les entrées ont changé sont recalculées.
Concrètement, sur GitHub Actions, activez la restauration du cache via actions/cache :
La clé combine le lockfile (pour invalider quand les deps bougent) et un hash des sources (pour un cache exact). La restore-key sert de fallback partiel. Sur notre pipeline, cette configuration ramène un build de 58 s à 12 s en moyenne, avec un taux de hit du cache de l'ordre de 85 %.
Turbopack dans un monorepo Turborepo
Sur un monorepo (pnpm workspaces + Turborepo est le combo que je rencontre le plus), il faut absolument déclarer turbopack.root. Sans ça, Turbopack scanne à la recherche du package.json racine et inclut potentiellement des dossiers voisins, ce qui dégrade la perf et peut créer des cycles de résolution :
Notez !.next/cache/** dans outputs : on exclut le cache Turbopack du cache Turborepo pour éviter la double indirection. Turbopack gère son propre cache mieux que Turborepo ne le ferait ; laissons chaque outil faire ce qu'il fait de mieux. Si vous voulez creuser la structure d'un monorepo Next.js moderne, l'article sur la migration middleware.ts vers proxy.ts couvre les patterns de partage de configuration entre apps.
Quelles fonctionnalités Turbopack ne supporte pas encore ?
La liste évolue vite, mais au moment où j'écris ces lignes voici ce qui n'est pas encore couvert dans la ligne 16.x et qui peut vous bloquer :
Module Federation : pas de support natif. Les équipes qui l'utilisent doivent rester sur webpack ou migrer vers un modèle de micro-frontends basé sur des routes indépendantes.
Plugins webpack tiers : CopyWebpackPlugin, BundleAnalyzerPlugin, etc. L'équivalent officiel pour l'analyse est @next/bundle-analyzer version 15.4+, qui a un adaptateur Turbopack.
Loaders qui émettent des assets supplémentaires : la plupart des loaders file-loader historiques doivent être remplacés par l'import statique natif de Next.js.
Certains transformers Babel : Turbopack utilise SWC, donc les presets et plugins Babel spécifiques doivent trouver un équivalent SWC ou être supprimés.
Custom source map plugins : hidden-source-map, nosources-source-map et le mode par défaut sont supportés ; les variantes exotiques ne le sont pas.
La meta-issue de suivi Turbopack sur GitHub reste la source de vérité. Je la consulte avant chaque go/no-go de migration client.
Déboguer les erreurs Turbopack en production
Les erreurs Turbopack ont un format légèrement différent des erreurs webpack, mais elles sont généralement plus lisibles. Trois patterns récurrents.
1. Module not found sur un import qui marchait avec webpack
Turbopack applique strictement les exports maps du package.json. Si un package legacy expose des fichiers via chemin direct (import x from 'lib/dist/x.js') sans le déclarer dans exports, Turbopack refuse. Solution : passer par l'API publique du package, ou ajouter le package à transpilePackages. J'ai croisé le cas très récemment avec une lib de charting maintenue en interne : deux lignes ajoutées au package.json et l'erreur a disparu.
2. Warnings sur les Server Components et les dépendances client
Turbopack détecte plus finement les imports interdits entre boundaries RSC. Un package qui importe window au top-level dans un chemin appelé depuis un Server Component sera flaggué. C'est un bug latent que webpack laissait passer ; la correction est de wrapper l'accès dans un 'use client' ou de charger dynamiquement.
3. Différences de hash de chunk entre builds
Si vous versionnez vos assets par hash, sachez que Turbopack calcule les hash différemment de webpack. Sur un CDN, cela signifie une invalidation complète lors du premier build Turbopack. Prévoyez la coordination avec l'équipe infra pour ne pas exploser les métriques cache-miss du CDN.
Benchmarks réels sur base 400+ routes
Voici les mesures que j'ai collectées sur une application SaaS de production que j'accompagne : 412 routes App Router, 87 composants Server, 14 routes API, environ 180 000 lignes de TypeScript, monorepo pnpm avec 8 packages internes. Les tests tournent sur un runner GitHub Actions ubuntu-latest (4 vCPU, 16 Go RAM).
Scénario
Webpack (Next.js 15)
Turbopack (Next.js 16)
Gain
Build production, cache froid
4 min 22 s
58 s
4.5×
Build production, cache chaud (1 fichier modifié)
1 min 47 s
12 s
8.9×
Dev server, démarrage à froid
18 s
2.4 s
7.5×
HMR, changement composant serveur
1.8 s
320 ms
5.6×
Mémoire peak
3.8 Go
1.2 Go
3.2×
La vraie surprise n'est pas dans la colonne « cache froid ». C'est le gain composé sur toute une journée de dev. Sur une équipe de 12 personnes, le temps CPU cumulé économisé par jour dépasse 4 heures. C'est le genre de chiffre qui débloque les budgets de migration en revue d'ingénierie.
Pour aller plus loin sur les stratégies de performance côté application, l'article sur Partial Prerendering (PPR) dans Next.js 16 complète bien ce guide : Turbopack accélère le build, PPR accélère le rendu. Et si vous mesurez déjà le coût de vos accès données, jetez un œil au Data Access Layer avec Drizzle ORM pour la partie runtime.
Questions fréquentes
Puis-je utiliser Turbopack et webpack en parallèle dans le même projet ?
Non, chaque exécution de next dev ou next build utilise un seul bundler. Vous pouvez cependant garder deux scripts build:webpack et build:turbopack dans le package.json pendant une phase de migration, et comparer les artefacts produits.
Turbopack fonctionne-t-il avec Vercel, Netlify et Cloudflare Pages ?
Oui. Vercel utilise Turbopack en interne. Netlify et Cloudflare Pages détectent le flag --turbopack dans les scripts et l'exécutent sans configuration additionnelle. Pour les runtimes edge, le comportement de sortie (edge-runtime) est identique à webpack.
Comment savoir si mon projet est prêt pour Turbopack ?
Lancez next build --turbopack une fois sur une branche isolée. Turbopack loggue chaque incompatibilité rencontrée avec un lien vers la docs de migration. Si le build passe et que les tests E2E passent aussi, vous êtes prêt.
Faut-il conserver le cache Turbopack entre commits ?
Oui, absolument. C'est là que se trouve la majorité du gain de vitesse en CI. Configurez actions/cache (ou l'équivalent chez votre provider CI) avec la clé .next/cache/turbopack keyed sur le lockfile et le hash des sources.
Turbopack remplace-t-il Turborepo ?
Non, les deux sont complémentaires. Turbopack est le bundler à l'intérieur d'un package Next.js. Turborepo est l'orchestrateur qui coordonne les builds entre plusieurs packages d'un monorepo. Utilisez les deux ensemble avec la configuration outputs montrée plus haut.
Activez le Partial Prerendering dans Next.js 16 pour combiner coque statique et trous dynamiques Suspense. Guide pratique avec exemples e-commerce et déploiement Vercel.
Chaque Server Action crée un endpoint HTTP public. Apprenez à sécuriser vos formulaires Next.js 16 avec useActionState, Zod, updateTag() et next-safe-action — avec des exemples TypeScript prêts à l'emploi.