Capítulo 284 de 456

Turbopack

Core Idea

Turbopack is the Rust-based incremental bundler built into Next.js and the default bundler as of v16.0.0 for both next dev and next build, offering a unified graph, incremental caching, and lazy bundling.

Key Concepts

  • Unified graph: single graph covers all output environments (client/server) instead of stitching separate compiler outputs together.
  • Incremental computation: parallelized across cores, cached down to the function level, persisted to disk between runs.
  • Lazy bundling: only bundles what the dev server actually requests, cutting initial compile time/memory.
  • import.meta.env: Turbopack-only, Vite-compatible env metadata object (DEV, PROD, MODE, BASE_URL, SSR), statically analyzed for dead-branch elimination.
  • import.meta.glob(): Turbopack-only, Vite-compatible glob-import API; lazy (thunks) by default, { eager: true } for direct imports, plus import, query, base, caseSensitive options.
  • Magic comments: turbopackIgnore, turbopackOptional (Turbopack-only) alongside webpack-compatible webpackIgnore; apply to dynamic import(), require(), require.resolve(), new Worker().
  • turbopack config key: next.config.js namespace for rules (loaders), resolveAlias, resolveExtensions, ignoreIssue.
  • --webpack flag: explicit opt-out back to Webpack, needed on platforms without native bindings (falls back to WASM, which doesn't support Turbopack).

Code Examples

if (import.meta.env.DEV) {
  console.log('development mode')
}
const { MODE, SSR } = import.meta.env
const baseUrl = import.meta.env['BASE_URL']
// Lazy (default): thunks
const modules = import.meta.glob('./dir/*.js')
for (const path in modules) {
  const module = await modules[path]()
}

// Eager
const eagerModules = import.meta.glob('./dir/*.js', { eager: true })

// Named export + query string
const defaults = import.meta.glob('./dir/*.js', { import: 'default' })
const rawFiles = import.meta.glob('./dir/*.txt', { query: '?raw' })

// Multiple patterns + negation
const combined = import.meta.glob(['./src/**/*.js', '!**/*.test.js'])
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  turbopack: {
    rules: {
      '*.txt': { condition: { query: '?raw' }, type: 'text' },
    },
    resolveAlias: { underscore: 'lodash' },
    resolveExtensions: ['.mdx', '.tsx', '.ts', '.jsx', '.js', '.json'],
  },
}

export default nextConfig
  • O que demonstra: as duas APIs exclusivas do Turbopack (import.meta.env, import.meta.glob) e a configuração básica via chave turbopack no next.config.ts.

Reference Tables

CategoryStatus
JS/TS, ESNext, CommonJS, ESMSupported (SWC-based)
BabelSupported automatically since Next.js 16 if a Babel config file is detected; node_modules excluded unless babel-loader manually configured
JSX/TSX, Fast Refresh, RSCSupported
Root layout auto-creationUnsupported — must create manually
Global CSS, CSS Modules, CSS Nesting, @import, PostCSSSupported
Sass/SCSSSupported; sassOptions.functions NOT supported (use webpack)
LessPlanned via plugins, not yet default
Lightning CSSIn use for CSS transforms; some legacy CSS Modules features unsupported
Static assets, JSON importsSupported
Path aliases, manual aliases, custom extensionsSupported via tsconfig.json / turbopack config
AMDPartially supported
Webpack pluginsNot supported (loaders are)
Yarn PnP, experimental.urlImports, experimental.esmExternalsNot planned
Magic commentWebpackTurbopack
webpackIgnore: trueYesYes
turbopackIgnore: trueNoYes
turbopackOptional: trueNoYes
webpackOptional: trueNoNo
Key experimental optionDefault (dev)Default (build)
turbopackFileSystemCacheForDevtrueN/A
turbopackFileSystemCacheForBuildN/Atrue
turbopackMinifyfalsetrue
turbopackSourceMapstrueproductionBrowserSourceMaps
turbopackRemoveUnusedImports/Exportsfalsetrue
turbopackScopeHoistingfalse (always off in dev)true
turbopackModuleIds'named''deterministic'

Anti-patterns

  • Using webpack's ~ tilde syntax for Sass node_modules imports: unsupported; drop the ~ or configure turbopack.resolveAlias: { '~*': '*' }.
  • Relying on sassOptions.functions custom JS-in-Sass functions: architecturally impossible under Turbopack's Rust engine; requires --webpack.
  • Assuming identical CSS decimal precision to webpack: Lightning CSS uses 5-digit precision vs webpack's 10 (e.g. line-height: 1.47059 vs 1.4705882353), which can shift pixel-level rendering.
  • Expecting webpack plugins to work: Turbopack has no plugin system, only loader support; find Turbopack-native alternatives or stay on webpack.
  • Relying on CSS import order across side-effect-free JS modules: Turbopack strictly follows JS import order for CSS Modules, which can differ from webpack's occasional reordering.

Key Takeaways

  1. Turbopack is zero-config for the vast majority of JS/TS/CSS/React use cases; explicit turbopack config is only needed for aliases, custom loaders, or extensions.
  2. import.meta.env and import.meta.glob are Turbopack-exclusive Vite-compatible APIs unavailable under webpack.
  3. Filesystem caching (turbopackFileSystemCacheForDev/ForBuild) persists compiler artifacts to disk, requiring the build environment to preserve .next/cache between runs to benefit.
  4. Migrating from webpack surfaces subtle diffs: CSS Modules ordering, Sass ~ imports, decimal precision, and dropped webpack-plugin support are the top gotchas.
  5. next dev --internal-trace generates a .next-profiles/trace-turbopack.bin file for reporting performance/memory issues upstream.

Connects To

  • ch269 next-cli: --turbopack/--webpack CLI flags and --experimental-cpu-prof profiling.
  • ch285 glossary: "Turbopack" glossary entry cross-references this page.