Turbopack Is Now the Default in Next.js 16: Your Complete Migration Guide (2026)
Turbopack is now the default bundler in Next.js 16 for both dev and build. Here's what changed, how to migrate from webpack, and what still breaks.
You've got a Next.js project. Somewhere in the depths of your next.config.ts there's a webpack config that's been growing since 2022 — custom loaders, a plugin here, a resolve alias there. You've been meaning to revisit it. With Next.js 16, you might actually have to.
Turbopack is no longer a beta experiment you opt into with a flag. It's the default bundler for both next dev and next build. No flags, no config, just faster builds out of the box. Here's everything you need to know to migrate cleanly — and what still breaks.
What Is Turbopack and Why Does It Matter?
Turbopack is Vercel's Rust-powered JavaScript bundler. It was built from the ground up as webpack's long-term successor — same mental model (modules, loaders, plugins) but written in Rust with an incremental computation engine that only reprocesses what actually changed between saves.
Where webpack rebuilds large portions of the dependency graph on each file change, Turbopack uses function-level caching. Even in a large codebase, only the affected modules and their direct dependents get recomputed. The result is that Fast Refresh feels nearly instant regardless of project size.
Real Performance Numbers
Based on Vercel's benchmarks and community-reported numbers from production projects:
Local dev server startup: ~10x faster (13s → 0.6s on large apps)
Fast Refresh: ~5x faster (3.1s → 180ms average)
Production builds: 2-3x faster on apps with 50+ pages
CI cold builds: improved by the new filesystem cache that now persists across runs
Numbers vary by project size, but even small projects see noticeably snappier dev server response. If you've got a monorepo with dozens of packages, the improvement is dramatic.
What Actually Changed in Next.js 16
Two concrete changes in Next.js 16 that affect every project:
Change #1: Turbopack is now the default for both next dev and next build. You no longer need to pass --turbopack. If you were already opting in via that flag, remove it.
Before (Next.js 15):
"scripts": {
"dev": "next dev --turbopack",
"build": "next build"
}After (Next.js 16):
"scripts": {
"dev": "next dev",
"build": "next build"
}Change #2: The turbopack config key moved out of experimental. If you had any Turbopack configuration, you need to update your next.config.ts:
// Next.js 15 (old - experimental)
export default {
experimental: {
turbopack: {
rules: {
'*.svg': {
loaders: ['@svgr/webpack'],
as: '*.js',
},
},
},
},
};
// Next.js 16 (new - top level)
export default {
turbopack: {
rules: {
'*.svg': {
loaders: ['@svgr/webpack'],
as: '*.js',
},
},
},
};Migrating from webpack: The Practical Checklist
If your project has a custom webpack config, here's the exact process to migrate without breaking production.
Step 1: Update Next.js
npm install next@16
# or
pnpm add next@16
# or
bun add next@16Step 2: Audit Your webpack Config
Open next.config.ts and look for a webpack key. If you don't have one, you're probably safe — just run next dev and check the console for warnings. If you do have custom webpack config, you'll hit a hard build error when running next build — Next.js 16 refuses to silently ignore a webpack config that could cause behavior differences in production.
Step 3: Translate Custom Loaders to Turbopack Rules
Most custom webpack loaders have a Turbopack equivalent. The syntax is different but the concept is the same. Here's the pattern for migrating a common MDX setup:
// Webpack loader (what you had before)
webpack: (config) => {
config.module.rules.push({
test: /\.mdx?$/,
use: ['babel-loader', '@mdx-js/loader'],
});
return config;
},
// Turbopack equivalent in next.config.ts
turbopack: {
rules: {
'*.mdx': {
loaders: ['@mdx-js/loader'],
as: '*.js',
},
},
},Turbopack loaders are applied right-to-left just like webpack, but you can only use loaders that Turbopack has first-class support for. Check the supported loaders list in the official Turbopack docs before assuming your loader will work — some popular ones are missing.
Step 4: Opt Back Into webpack If Blocked
If you're blocked by an incompatible plugin, you can temporarily opt back into webpack while you work on migration:
# Opt out for builds
next build --no-turbopack
# Or in package.json scripts
"build": "next build --no-turbopack"This is an escape hatch, not a long-term strategy. The --no-turbopack flag will likely be deprecated in a future version.
Common Breakage Points (and How to Fix Them)
Based on community migration reports, here's what actually breaks and what to do about it:
webpack-bundle-analyzer: Switch to
@next/bundle-analyzerwhich has native Turbopack support.Module Federation: Not supported yet in Turbopack. This is a known limitation — stick with webpack if you're using MF.
Custom Babel transforms: Turbopack uses SWC by default. Check if your Babel plugin has an SWC counterpart — most popular ones do at this point.
CSS Modules cross-file composition: Complex
composes: ... frompatterns across files can behave differently. Test thoroughly before shipping.resolve.alias for monorepos: Use
turbopack.resolveAliasinstead of the webpackresolve.aliasconfig.
A Clean Next.js 16 Config (What It Looks Like)
Here's what a production-ready next.config.ts looks like after migrating off webpack — handling SVGs, monorepo aliases, and MDX:
import type { NextConfig } from 'next';
const config: NextConfig = {
// Turbopack is default — only add this block if you need customization
turbopack: {
rules: {
// SVG as React components via @svgr/webpack
'*.svg': {
loaders: ['@svgr/webpack'],
as: '*.js',
},
// MDX support
'*.mdx': {
loaders: ['@mdx-js/loader'],
as: '*.js',
},
},
resolveAlias: {
// Monorepo package aliases
'@ui': './packages/ui/src',
'@lib': './packages/lib/src',
},
},
// Everything else works exactly the same
images: {
domains: ['cdn.example.com'],
},
};
export default config;Notice there's no webpack key anywhere. That's the goal.
When to Stick With webpack (For Now)
Turbopack is the future, but here are legitimate reasons to stay on webpack a bit longer:
You're using Module Federation and can't migrate the entire architecture right now
Your project relies on a webpack plugin that has no Turbopack equivalent yet
You're running CI in containers with very strict memory limits — Turbopack has a higher peak memory ceiling during builds
You have a large enterprise monorepo where the Turbopack compatibility surface hasn't been fully validated yet
None of these are permanent blockers. The Turbopack team is actively closing the plugin compatibility gap, and Module Federation support is explicitly on the public roadmap.
TL;DR
Next.js 16 makes Turbopack the default for both
next devandnext buildMove
experimental.turbopackto the top-levelturbopackkey in your configNo custom webpack config? Zero migration work needed — just update and go
Custom webpack loaders? Translate them to
turbopack.rulessyntaxModule Federation users: hold off for now, stay on webpack
Need an escape hatch? Use
next build --no-turbopacktemporarily while you migrate