Turbopack is the Rust-based bundler from Vercel that replaces webpack with up to 700x faster updates, and this guide shows you exactly how to use it in production.
Turbopack isn't just another bundler — it's a fundamental shift in how we compile JavaScript. Built on the same incremental architecture as SWC, it caches at the module level rather than the chunk level, which means your dev server starts in milliseconds and hot updates feel instant. I've been using it daily for the past year, and the difference between webpack's 3-second reloads and Turbopack's sub-100ms updates genuinely changes how I work.
Why Turbopack Matters (and When to Skip It)
The bundler landscape has been stagnant for a decade. webpack works, but it's slow, complex, and requires a PhD in configuration to optimize. Turbopack fixes this by doing the heavy lifting in Rust and caching aggressively at every layer.
Here's my take: if you're starting a new Next.js project, don't even think about webpack. Use Turbopack. If you're on an existing webpack project with more than 50k lines of code, the migration cost might not be worth the speed gain yet. Turbopack's ecosystem support is still maturing — some plugins like webpack-dev-middleware and certain loaders don't have equivalents yet.
Getting Started with Turbopack
The simplest way to start is with Next.js, which has first-class Turbopack support. Create a new project and run it with the --turbo flag:
npx create-next-app@latest my-turbo-app --typescript
cd my-turbo-app
npm run dev -- --turbo
You'll notice the dev server starts almost instantly. For a standalone Turbopack setup outside Next.js, you can use it directly with the Turbopack CLI:
npm install -g @turbopack/cli
turbo dev ./src/index.ts
You'll need a turbo.json file to configure the entry points:
{
"$schema": "https://turbopack.dev/schema.json",
"dev": {
"entry": "./src/index.ts",
"output": "./dist",
"port": 3000
}
}
Core Turbopack Concepts Every Developer Should Know
1. Incremental Caching
Turbopack caches at the module level, not the bundle level. When you change one file, only that file's compilation result is invalidated. Here's how the caching layer works under the hood:
// This module gets cached independently
export const expensiveComputation = (input: number): number => {
// Turbopack caches the result of this module's compilation
return input * 2;
};
2. Module Graphs
Instead of building the entire dependency tree upfront, Turbopack builds a lazy module graph. It only compiles what's needed for the current route. This is why page transitions in dev feel instant — the next page's modules compile on demand.
// With Turbopack, this import is lazy by default in dev
const Analytics = await import('./analytics');
// Only compiles when you navigate to a route that uses it
export default function Dashboard() {
return <Analytics />;
}
3. SWC-based Transformations
Turbopack uses SWC for all JavaScript/TypeScript transformations. This means no more Babel config files. If you need custom transforms, you write them as SWC plugins in Rust or use the JavaScript API:
// turbo.config.ts
import type { TurbopackConfig } from 'turbopack';
export default {
module: {
rules: [
{
test: /\.svg$/,
use: ['@svgr/webpack'], // compatible with webpack loaders
},
],
},
} satisfies TurbopackConfig;
4. Native Module Support
Turbopack handles Node.js native modules out of the box. No more node-loader hacks:
// This just works with Turbopack
import { createHash } from 'node:crypto';
import sharp from 'sharp'; // native module — no extra config needed
Common Turbopack Mistakes and How to Fix Them
Mistake 1: Mixing webpack Plugins Without Checking Compatibility
I've seen developers blindly copy their next.config.js plugins into Turbopack. Most webpack plugins won't work because Turbopack uses a different plugin API.
// This will fail silently
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
// Fix: check if the plugin supports Turbopack, or skip it in dev
module.exports = {
...(process.env.NODE_ENV === 'production' ? withBundleAnalyzer({}) : {}),
};
Mistake 2: Assuming All CSS Features Work
Turbopack supports CSS Modules and global CSS, but some advanced PostCSS plugins have compatibility gaps. If you're using Tailwind, make sure you're on v3.3 or later.
/* This works fine in Turbopack */
.module-class {
@apply bg-blue-500;
}
Mistake 3: Not Leveraging Turbopack's WebAssembly Support
Turbopack compiles WASM modules natively. Many developers still use JavaScript fallbacks when they could use WASM for heavy computations:
// Use WASM directly — Turbopack handles the compilation
import init, { analyze } from './wasm-module/pkg';
await init();
const result = analyze(new Uint8Array(buffer));
When Should You Use Turbopack?
Use Turbopack when you're building with Next.js 13.4+ or when you need sub-second hot reloads for a large React codebase. It's also ideal for monorepos since the caching layer is shared across projects. Skip it if you rely heavily on custom webpack plugins that haven't been ported, or if you're working with legacy build tooling that has strict webpack-specific configurations.
For API routes and serverless functions, Turbopack's production build still has some rough edges compared to webpack. If you're deploying to edge functions, test thoroughly — I've hit edge cases with dynamic imports in production mode that worked fine in dev.
Turbopack in Production
First, always use the --turbo flag in your production build for Next.js. The Rust-based minifier alone cuts build times by 40-60% compared to Terser:
next build --turbo
Second, configure persistent caching for CI. Turbopack stores caches in .next/cache by default, but you can point it to a shared location:
{
"experimental": {
"turbopack": {
"cacheDir": "/shared/cache/turbopack"
}
}
}
Third, monitor your bundle sizes carefully. Turbopack's lazy loading in dev can mask how large your production bundles actually are. Use next build with the --analyze flag to catch bloat early.
The one thing I'd tell every developer: try Turbopack on a side project this week. Create a Next.js app, run it with --turbo, and feel the difference in your dev loop. Once you experience sub-100ms hot reloads, you'll never want to go back to webpack.