JavaScript bundling has lengthy been the efficiency ceiling for big Subsequent.js initiatives. Gradual sizzling module alternative, painful chilly begins exceeding 10 seconds on sizeable codebases, and costly CI builds that eat via compute minutes have outlined the developer expertise for years. Turbopack’s stabilization in Subsequent.js 15 delivers the most important measured pace enchancment the framework has shipped because the App Router: Vercel’s benchmarks report as much as 76% quicker chilly begins in comparison with Webpack.
Turbopack is not hidden behind an experimental flag for improvement. As of Subsequent.js 15, it ships as a steady, default-ready bundler for subsequent dev, with energetic progress towards manufacturing construct help. This tutorial covers the total path: enabling Turbopack, configuring it for real-world stacks, benchmarking precise efficiency positive factors, troubleshooting widespread breakages, and assessing manufacturing readiness.
Desk of Contents
What Is Turbopack and Why It Issues
Turbopack vs. Webpack: Structure at a Look
Turbopack is a Rust-based incremental computation engine designed as Webpack’s successor throughout the Subsequent.js ecosystem. The place Webpack processes and bundles modules via a JavaScript-based pipeline, Turbopack makes use of Rust’s efficiency traits alongside two key architectural choices: function-level caching and lazy bundling. Operate-level caching (the place every transformation step is individually memoized by its inputs) means Turbopack remembers the results of each computation and solely recomputes what has modified. Lazy bundling means it solely processes modules truly requested by the browser, quite than eagerly constructing a complete dependency graph upfront.
That is distinct from instruments like Vite, which makes use of esbuild for dependency pre-bundling and native ES modules for dev serving. Turbopack takes a special method, working as a unified incremental engine quite than composing a number of instruments.
Operate-level caching (the place every transformation step is individually memoized by its inputs) means Turbopack remembers the results of each computation and solely recomputes what has modified.
Stability Milestones in Subsequent.js 15
Turbopack’s journey started as an experimental flag in Subsequent.js 13, matured via Subsequent.js 14 with expanded take a look at protection, and reached steady standing for subsequent dev in Subsequent.js 15. Turbopack is marked steady as a result of it handed the Subsequent.js integration take a look at suite on the time of the Subsequent.js 15 launch. Examine the Subsequent.js 15 launch notes for the precise pass-rate threshold and methodology. The subsequent construct --turbo path stays in energetic improvement. To test its present standing, go to the Turbopack API reference or run npx subsequent construct --turbo and examine the warning banner within the output. If nonetheless experimental, Subsequent.js prints a warning; if steady, no warning seems.
Enabling Turbopack in Your Subsequent.js 15 Mission
Recent Mission Setup
Ranging from scratch is the best path. Creating a brand new mission and launching the dev server with Turbopack requires simply two instructions:
npx create-next-app@newest my-turbo-app
cd my-turbo-app
npx subsequent dev --turbo
That is the zero-config completely satisfied path. Subsequent.js 15’s scaffolding produces a mission construction absolutely appropriate with Turbopack out of the field, with no extra configuration information or dependencies required.
Migrating an Present Mission
For current initiatives, the migration entails updating the dev script in bundle.json and reviewing subsequent.config.js for any Webpack-specific configuration that wants translation:
{
"scripts": {
"dev": "subsequent dev --turbo",
"construct": "subsequent construct",
"begin": "subsequent begin",
"lint": "subsequent lint"
}
}
If the mission makes use of a subsequent.config.js with customized Webpack configuration, these customizations will should be migrated to Turbopack’s configuration floor (lined within the configuration part under). Earlier than operating, confirm the mission meets the minimal necessities: Subsequent.js 15 or later and Node.js 18.18.0 or later. Run npm ls subsequent or yarn why subsequent to verify peer dependency alignment — search for subsequent@15.x.x within the output to verify the put in model — significantly if the mission makes use of packages that pin particular Subsequent.js variations.
Verifying Turbopack Is Lively
After launching the dev server, the terminal output explicitly confirms which bundler is operating. Search for this within the startup log:
â–² Subsequent.js 15.x.x
- Native: http://localhost:3000
- Turbopack prepared
The presence of “Turbopack prepared” (versus the usual Webpack compilation messages) confirms the swap took impact. If the output exhibits “compiled efficiently” with Webpack-style chunk info as a substitute, Turbopack shouldn’t be energetic and the --turbo flag might not be reaching the dev command accurately. Double-check the bundle.json script or move the flag immediately through the command line.
Benchmarking the Pace Wins
Chilly Begin Time
Measuring chilly begin time requires a managed, reproducible method. The next shell script compares startup occasions between Webpack and Turbopack by clearing caches and timing the preliminary server prepared occasion:
#!/bin/bash
PORT=3099
WAIT_TIMEOUT=60000
clear_caches() {
[ -d ".next" ] && rm -rf .subsequent
[ -d "node_modules/.cache" ] && rm -rf node_modules/.cache
}
run_timed() {
native label="$1"
native turbo_flag="$2"
clear_caches
echo "--- ${label} ---"
npx subsequent dev --port "$PORT" ${turbo_flag} &
DEV_PID=$!
START=$(date +%spercentN)
if ! npx wait-on --timeout "$WAIT_TIMEOUT" "http://localhost:${PORT}"; then
echo "ERROR: dev server didn't begin inside timeout." >&2
kill "$DEV_PID" 2>/dev/null
return 1
fi
END=$(date +%spercentN)
echo "${label}: $(( (END - START) / 1000000 ))ms"
kill "$DEV_PID" 2>/dev/null
wait "$DEV_PID" 2>/dev/null
}
run_timed "Webpack Chilly Begin" ""
run_timed "Turbopack Chilly Begin" "--turbo"
Vercel’s printed benchmarks report as much as 76% quicker chilly begins with Turbopack in comparison with Webpack. This determine comes from Vercel’s Turbopack benchmarks web page (see turbo.construct/pack/docs/benchmarks for methodology particulars, together with mission dimension and {hardware} specs). Actual-world outcomes will range relying on machine {hardware}, mission dimension, dependency rely, and working system. Run the script above towards your individual mission and evaluate to your Webpack baseline quite than treating 76% as a assured determine.
Scorching Module Alternative (HMR)
Turbopack’s HMR pace benefit stems immediately from its incremental computation mannequin. When a developer edits a deeply nested part, Turbopack doesn’t re-bundle your entire utility and even your entire route. It recomputes solely the capabilities affected by the change and sends a minimal replace to the browser. In observe, this implies enhancing a part 5 ranges deep in a part tree sometimes produces a browser replace in underneath 200ms for single-file edits, quite than the multi-second delay widespread in massive Webpack initiatives.
To measure this your self, open the browser devtools Community panel, filter by HMR occasions, edit a deeply nested part, and observe the elapsed milliseconds between save and replace. The distinction is most noticeable on initiatives with a whole bunch of modules.
Modifying a part 5 ranges deep in a part tree sometimes produces a browser replace in underneath 200ms for single-file edits, quite than the multi-second delay widespread in massive Webpack initiatives.
Giant Codebase Concerns
Pace positive factors from Turbopack scale non-linearly with mission dimension. A small mission with 20 routes and minimal dependencies may even see underneath 20% enchancment, as a result of Webpack was already quick sufficient. Initiatives with 500+ routes, deep part timber, and a fancy dependency graph are the place Turbopack’s lazy bundling and function-level caching present the most important hole. To quantify this to your codebase, run the cold-start benchmark on each a small route subset and the total mission, then evaluate the ratios. The important thing elements are route rely, part tree depth, and the full variety of nodes within the dependency graph.
Configuring Turbopack for Your Stack
Customized Webpack Configurations: What Carries Over
Turbopack gives its personal config keys underneath turbopack in subsequent.config.js. This key requires Subsequent.js 15. Confirm your put in model with npm ls subsequent to verify the secret’s acknowledged — should you see an “Invalid subsequent.config.js possibility” warning on startup, seek the advice of the Subsequent.js docs to your particular model’s config construction. Widespread Webpack customizations like loader guidelines and path aliases translate to this new construction:
const path = require('path');
const nextConfig = {
turbopack: {
guidelines: {
'**/*.svg': {
loaders: ['@svgr/webpack'],
as: '*.js',
},
},
resolveAlias: {
'@parts': path.resolve(__dirname, './src/parts'),
'@utils': path.resolve(__dirname, './src/utils'),
},
},
};
module.exports = nextConfig;
This instance demonstrates two of the commonest migration wants: dealing with SVG imports via a loader and configuring path aliases. The guidelines key replaces Webpack’s module.guidelines for specifying loaders, whereas resolveAlias replaces resolve.alias. Observe that @svgr/webpack is a Webpack-specific loader; confirm its compatibility with Turbopack’s loader interface earlier than counting on it in your mission. If points come up, take into account @svgr/rollup or a local Turbopack rework as alternate options. The resolveAlias values should be absolute paths — use path.resolve(__dirname, '...') quite than naked relative strings, which resolve towards an inner working listing and produce silent module-not-found failures.
Dealing with Unsupported Webpack Plugins
Turbopack doesn’t help plugins that deeply hook into Webpack’s compilation lifecycle, akin to webpack-bundle-analyzer or customized plugins utilizing compiler.hooks. For initiatives that rely upon these throughout improvement, the swish fallback is sustaining a second script in bundle.json:
{
"scripts": {
"dev": "subsequent dev --turbo",
"dev:webpack": "subsequent dev"
}
}
This permits builders to drop again to Webpack for particular edge instances with out abandoning Turbopack because the default improvement expertise.
Setting Variables and Function Flags
Setting variable dealing with through .env, .env.native, .env.improvement, and .env.take a look at information works identically underneath Turbopack. Turbopack resolves .env information in the identical order as Webpack and handles the NEXT_PUBLIC_ prefix identically. That mentioned, verifying atmosphere variable availability within the browser after switching to Turbopack is a worthwhile smoke take a look at, significantly for initiatives that depend on build-time variable inlining.
Manufacturing Readiness: The place Turbopack Stands Immediately
subsequent dev --turbo vs. subsequent construct --turbo
The important distinction: subsequent dev --turbo is steady and examined. subsequent construct --turbo is in energetic improvement and should carry experimental or alpha standing. This implies manufacturing builds at the moment nonetheless use Webpack. This cut up works advantageous in observe. The event bundler and the manufacturing bundler don’t should be the identical instrument, and Subsequent.js has at all times maintained separate optimization paths for dev and construct. Builders get Turbopack’s pace throughout iteration whereas manufacturing output continues to make use of Webpack’s mature optimization pipeline.
CI/CD Pipeline Changes
CI/CD configurations ought to use Turbopack for improvement server duties (operating checks towards the dev server, smoke checks) whereas protecting the usual construct for manufacturing artifacts. Make sure the dev script in bundle.json contains the --turbo flag (as proven within the migration part above), since Turbopack is activated through the CLI flag, not through atmosphere variables:
identify: CI
on: [push, pull_request]
jobs:
take a look at:
runs-on: ubuntu-newest
steps:
- makes use of: actions/checkout@v4
- makes use of: actions/setup-node@v4
with:
node-version: '18.18.0'
cache: 'npm'
- run: npm ci
- run: |
npm run dev -- --port 3099 &
echo $! > /tmp/dev.pid
shell: bash
- run: npx wait-on --timeout 60000 http://localhost:3099
- run: npm take a look at
- identify: Cleanup dev server
if: at all times()
run: kill $(cat /tmp/dev.pid) 2>/dev/null || true
construct:
runs-on: ubuntu-newest
steps:
- makes use of: actions/checkout@v4
- makes use of: actions/setup-node@v4
with:
node-version: '18.18.0'
cache: 'npm'
- run: npm ci
- run: npm run construct
This workflow runs checks towards the Turbopack dev server for pace whereas the manufacturing construct step makes use of Webpack for stability. The dev server course of PID is captured so cleanup runs reliably even when a previous step fails.
Testing Parity
Run your full take a look at suite underneath Turbopack’s dev server earlier than committing to the swap. The purpose is surfacing any bundler-specific variations. Widespread gotchas embody dynamic imports that behave otherwise underneath lazy bundling (for instance, a dynamic(() => import(...)) name might resolve in a special chunk order, inflicting hydration mismatches in checks), customized Babel transforms that want SWC equivalents, and CSS-in-JS libraries (significantly styled-components and Emotion) that require particular SWC rework settings in subsequent.config.js quite than Babel plugins.
Troubleshooting Widespread Points
“Module Not Discovered” After Enabling Turbopack
When you see Module not discovered: Cannot resolve '@parts/...' instantly after switching, the issue is nearly at all times path alias decision. Turbopack resolves aliases from tsconfig.json (or jsconfig.json) paths, however refined variations in how wildcards and base URLs are interpreted could cause modules to go unresolved. Confirm that tsconfig.json paths match precisely what Turbopack expects, together with trailing /* patterns on listing aliases. Additionally be sure that any resolveAlias entries in subsequent.config.js use absolute paths (through path.resolve(__dirname, '...')) quite than naked relative strings.
Styling Breakages
Examine these so as: CSS Modules and Tailwind CSS v3.x work with Turbopack with out extra configuration. Tailwind CSS v4 customers ought to confirm PostCSS plugin compatibility, as v4 makes use of a special configuration mannequin. Sass requires confirming that the loader is configured underneath the turbopack.guidelines key in subsequent.config.js. For styled-components or Emotion, confirm that the SWC rework settings are enabled in subsequent.config.js underneath the compiler key, as Turbopack makes use of SWC quite than Babel for these transforms.
Third-Social gathering Package deal Incompatibilities
When a bundle fails silently or throws an unfamiliar error, allow diagnostic tracing first. Setting NEXT_TURBOPACK_TRACING=1 earlier than launching the dev server produces hint logs that assist determine which module or rework is failing. If no hint output seems, seek the advice of the Turbopack troubleshooting docs for the present variable identify, as it might change throughout variations. Report confirmed incompatibilities to the Turbopack GitHub repository to assist the workforce prioritize fixes.
Full Implementation Guidelines
- Affirm Subsequent.js 15+ and Node.js 18.18.0+ are put in.
- Replace the
bundle.jsondev script tosubsequent dev --turbo. - Migrate customized Webpack loaders to the
subsequent.config.jsturbopackkey, verifying every loader’s Turbopack compatibility individually. - Confirm Turbopack activation by checking for “Turbopack prepared” in terminal output.
- Benchmark chilly begin and HMR towards the Webpack baseline utilizing timed runs.
- Run the total take a look at suite underneath the Turbopack dev server and diff the outcomes towards your Webpack take a look at output.
- Audit third-party packages for compatibility; allow
NEXT_TURBOPACK_TRACINGfor diagnostics. - Replace CI/CD pipelines: Turbopack for dev/take a look at steps, customary construct for manufacturing.
- Monitor
subsequent construct --turboimprovement progress for future full adoption. - Doc any fallback configurations and recognized incompatibilities for the workforce so the following individual doesn’t rediscover them.
Abstract and Subsequent Steps
Turbopack in Subsequent.js 15 delivers measurable pace wins the place they matter most: chilly begin occasions decreased by as much as 76% based on Vercel’s benchmarks (see turbo.construct/pack/docs/benchmarks for methodology), sub-200ms HMR for single-file edits via incremental computation, and a noticeably quicker suggestions loop throughout improvement. Use Turbopack for improvement as we speak, hold Webpack for manufacturing builds till subsequent construct --turbo reaches steady, and benchmark towards your individual mission baselines quite than counting on generic numbers.
Use Turbopack for improvement as we speak, hold Webpack for manufacturing builds till
subsequent construct --turboreaches steady, and benchmark towards your individual mission baselines quite than counting on generic numbers.
Begin right here: run npx subsequent dev --turbo, open your largest web page, and time the chilly begin towards your present Webpack baseline.
Supply hyperlink


