0Pricing
Next.js 15 Fullstack (App Router + Server Actions) · Lección

Análisis profundo de la configuración de Turbopack y del compilador

Ajuste Turbopack, las transformaciones y el compilador basado en SWC para acelerar las compilaciones y reducir la salida.

Análisis profundo de la configuración de Turbopack y del compilador es una lección gratuita de Next.js 15 Fullstack (App Router + Server Actions) en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Next.js 15 Fullstack (App Router + Server Actions), y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Next.js 15 Fullstack (App Router + Server Actions) incluye 4 lecciones en total.

Partes de esta lección aún no han sido traducidas y se muestran en inglés.

Why Turbopack Exists

Next.js 15 ships Turbopack as the default bundler for next dev. It was built in Rust to replace the JavaScript-based Webpack pipeline that powered Next.js for years.

The core problem Webpack faced at scale: every file change triggered a JavaScript graph traversal and re-evaluation. At 10,000 modules, a single edit could take 8–15 seconds before HMR landed in the browser.

Turbopack solves this with three architectural bets:

  • Incremental computation — only the modules affected by a change are re-evaluated, not the whole graph.
  • Parallel compilation — Rust's fearless concurrency lets multiple CPU cores transform files simultaneously.
  • Persistent caching — transform results are stored on disk and survive process restarts.

The result: cold start times drop by roughly 50–75% on large apps, and HMR latency falls to single-digit milliseconds in most cases.

Enabling Turbopack in next.config.ts

In Next.js 15, next dev --turbopack is the recommended way to opt in during development. For production builds, Webpack remains the default until Turbopack reaches full parity, so you control the flag per command in package.json.

You can also embed Turbopack options directly inside next.config.ts under the experimental.turbo key (renamed to turbopack in the stable API).

Key points to keep in mind:

  • The turbopack key only affects next dev; production builds still use Webpack unless you pass --turbopack to next build (experimental in v15).
  • Options in turbopack are merged on top of Turbopack's built-in defaults — you never have to replicate the full config.
  • The TypeScript config file (next.config.ts) gives you full type safety for these options via the NextConfig type.
// next.config.ts
import type { NextConfig } from 'next';

const config: NextConfig = {
  turbopack: {
    // Turbopack-specific options go here
    // (rules, resolveAlias, resolveExtensions, etc.)
  },
};

export default config;

Turbopack Loaders: Replacing Webpack Rules

Webpack used module.rules with loaders like babel-loader or raw-loader. Turbopack has an equivalent called rules inside the turbopack config block.

Each rule maps a file-extension glob to one or more Turbopack-compatible loaders. Note that Webpack loaders are not directly compatible — Turbopack requires loaders that implement its own transform API, though many popular loaders (e.g. @svgr/webpack, @mdx-js/loader) have published Turbopack-compatible versions.

Anatomy of a rule:

  • test — a glob or regex string matching file paths
  • use — an array of loader objects, each with a loader package name and an optional options object

Loaders run right-to-left, exactly as in Webpack.

// next.config.ts
import type { NextConfig } from 'next';

const config: NextConfig = {
  turbopack: {
    rules: {
      // Transform .svg files into React components
      '*.svg': {
        loaders: ['@svgr/webpack'],
        as: '*.js',
      },
      // Transform raw .txt files into string modules
      '*.txt': {
        loaders: ['raw-loader'],
        as: '*.js',
      },
    },
  },
};

export default config;

Module Aliases with resolveAlias

Path aliases let you write import { Button } from '@ui/Button' instead of ../../components/ui/Button. Turbopack supports this via turbopack.resolveAlias, which mirrors Webpack's resolve.alias.

You should also keep your tsconfig.json paths in sync — the TypeScript compiler uses paths for type checking, while Turbopack uses resolveAlias for bundling. A mismatch causes "module not found" errors at build time even though types look correct in your editor.

Common pattern: define the canonical mapping in one place and derive both configs from it, or use next/jest which auto-reads tsconfig.json paths for Jest.

// next.config.ts
import type { NextConfig } from 'next';
import path from 'path';

const config: NextConfig = {
  turbopack: {
    resolveAlias: {
      '@ui': path.resolve(__dirname, 'src/components/ui'),
      '@lib': path.resolve(__dirname, 'src/lib'),
      '@server': path.resolve(__dirname, 'src/server'),
    },
  },
};

export default config;

// tsconfig.json (keep in sync)
// {
//   "compilerOptions": {
//     "paths": {
//       "@ui/*": ["./src/components/ui/*"],
//       "@lib/*": ["./src/lib/*"],
//       "@server/*": ["./src/server/*"]
//     }
//   }
// }

SWC: Next.js's Built-in Compiler

Alongside Turbopack, Next.js uses SWC (Speedy Web Compiler) as its code transformer. SWC is also written in Rust and handles TypeScript stripping, JSX transformation, minification, and optional syntax transforms.

Important distinction:

  • Turbopack is the bundler — it builds the module graph, resolves imports, and orchestrates code splitting.
  • SWC is the transformer — it converts individual files (TS → JS, JSX → React.createElement calls, etc.).

Both are active by default in Next.js 15. SWC replaces Babel for most projects; if you still have a .babelrc in your repo, Next.js will fall back to Babel and disable SWC — this is a common source of slow builds on migrated projects.

To confirm SWC is active, run next build and look for "SWC minify" in the output.

Configuring SWC Transforms in next.config.ts

SWC transforms are configured at the top level of NextConfig (not inside turbopack). The most commonly tuned options are:

  • compiler.styledComponents — enables the SWC plugin for styled-components, adding display names and deterministic class names.
  • compiler.emotion — same for the Emotion CSS-in-JS library.
  • compiler.removeConsole — strips console.* calls from production builds. You can whitelist specific methods (e.g. keep console.error).
  • compiler.reactRemoveProperties — removes custom React props (like data-testid) from production output, reducing HTML payload.

These transforms run on every file during compilation, so enabling only what you need keeps build times tight.

// next.config.ts
import type { NextConfig } from 'next';

const isProd = process.env.NODE_ENV === 'production';

const config: NextConfig = {
  compiler: {
    // Remove console.log but keep console.error in production
    removeConsole: isProd
      ? { exclude: ['error', 'warn'] }
      : false,

    // Strip data-testid attributes from JSX in production
    reactRemoveProperties: isProd
      ? { properties: ['^data-testid$'] }
      : false,

    // Enable styled-components SWC plugin
    styledComponents: true,
  },
};

export default config;

SWC Minification vs Terser

Next.js 15 uses SWC for minification by default (swcMinify: true is now the implicit default). This replaces Terser, the JavaScript-based minifier that was standard for years.

Benchmark comparison on a medium Next.js app (~300 modules):

  • Terser: ~18 seconds minification during next build
  • SWC minifier: ~3 seconds — roughly 6× faster

SWC minification is also scope-aware and performs dead-code elimination (DCE) at the module level. Combined with tree-shaking from the bundler, this means unused exports that Terser might have kept can be eliminated.

If you encounter an edge case where SWC minification produces incorrect output (rare but possible), you can opt back to Terser:

// next.config.ts — only needed if SWC minifier causes issues
import type { NextConfig } from 'next';

const config: NextConfig = {
  // Explicitly disable SWC minification and fall back to Terser
  swcMinify: false,
};

export default config;

// Alternatively, to tune SWC minification behavior:
// (no direct config exposed yet — SWC minifier config is internal)
// The recommended approach is to leave swcMinify: true (default)
// and report any correctness bugs to the Next.js GitHub repo.

Bundle Analyzer: Visualizing What You Ship

Before optimizing bundle size, you need to see it. The @next/bundle-analyzer package wraps webpack-bundle-analyzer and integrates it with Next.js builds.

After setup, running ANALYZE=true next build opens an interactive treemap in your browser showing every module and its contribution to each JS chunk.

What to look for:

  • Large node_modules — e.g. moment.js (>70 KB gzipped) when you only need date formatting. Replace with date-fns or native Intl.DateTimeFormat.
  • Duplicate packages — two versions of react or lodash appearing in the treemap signals a resolution conflict.
  • Server vs Client chunks — code that belongs on the server leaking into the client bundle (e.g. a DB client).

Note: bundle-analyzer currently works with the Webpack build (next build without --turbopack). A Turbopack-native analyzer is on the roadmap.

// next.config.ts
import type { NextConfig } from 'next';
import bundleAnalyzer from '@next/bundle-analyzer';

const withBundleAnalyzer = bundleAnalyzer({
  enabled: process.env.ANALYZE === 'true',
  openAnalyzer: true,
});

const config: NextConfig = {
  // ... your other config
};

export default withBundleAnalyzer(config);

// package.json script:
// "analyze": "ANALYZE=true next build"

Turbopack Persistent Cache Configuration

Turbopack's persistent cache stores transform and bundling artifacts in .next/cache/turbopack. On a second next dev run (or in CI after cache restoration), Turbopack reads from disk instead of recomputing — dramatically reducing cold-start time for CI pipelines.

Key behaviors to understand:

  • The cache is content-addressed: a file's cache key is a hash of its content plus the content of all its dependencies. You will never get a stale cache hit.
  • The cache directory can grow large over time. next dev has a built-in LRU eviction policy, but you can wipe it manually with rm -rf .next/cache/turbopack.
  • In CI, cache the .next/cache directory between runs. GitHub Actions example:
# .github/workflows/ci.yml (relevant excerpt)
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Restore Next.js cache
        uses: actions/cache@v4
        with:
          path: |
            ~/.npm
            ${{ github.workspace }}/.next/cache
          key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.ts','**/*.tsx') }}
          restore-keys: |
            ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-

      - run: npm ci
      - run: npm run build

Controlling Code Splitting and Chunk Strategy

Next.js automatically code-splits at the route level (each page gets its own JS chunk), but you can further influence splitting with two techniques:

1. Dynamic imports (next/dynamic) — lazily load heavy components so they are excluded from the initial page bundle. This is the primary tool for reducing First Load JS.

2. optimizePackageImports — a Next.js 15 config option that tells the compiler to tree-shake specific packages that don't have proper ESM exports. Libraries like lucide-react, @radix-ui/*, and icon packs often benefit from this.

Both techniques work with Turbopack and Webpack. optimizePackageImports is especially powerful because it requires zero changes to your import statements — it's purely a bundler hint.

// next.config.ts
import type { NextConfig } from 'next';

const config: NextConfig = {
  // Tell the compiler to tree-shake these packages
  // even if they lack proper ESM export maps
  experimental: {
    optimizePackageImports: [
      'lucide-react',
      '@radix-ui/react-icons',
      'recharts',
      '@heroicons/react',
    ],
  },
};

export default config;

// In your component — no change needed:
// import { ChevronRight, User } from 'lucide-react';
// Only ChevronRight and User are bundled, not the full icon library.

Measuring Build Performance with next build --profile

When build times spike unexpectedly, Next.js provides built-in profiling to pinpoint bottlenecks. Two flags are most useful:

  • next build --profile — emits a React profiler trace and a .cpuprofile file you can open in Chrome DevTools to see which transforms or plugins are consuming time.
  • NEXT_TELEMETRY_DEBUG=1 next build — prints detailed timing breakdowns per phase (compilation, type checking, static generation, etc.) to stdout.

For Turbopack specifically, the --turbopack flag surfaces compile times per route segment in the terminal output. A single route taking disproportionately long often indicates a missing resolveAlias causing Turbopack to traverse a deep relative path on every HMR cycle.

Practical workflow: run with profiling → identify the slowest phase → apply the relevant config change → re-measure. Never guess at optimizations on a complex bundler.

// scripts/build-perf.ts — a small helper to time build phases
// Run with: npx ts-node scripts/build-perf.ts

import { execSync } from 'child_process';

function timed(label: string, cmd: string): void {
  const start = Date.now();
  console.log(`\n>>> Starting: ${label}`);
  try {
    execSync(cmd, { stdio: 'inherit', env: { ...process.env } });
  } catch {
    console.error(`[FAILED] ${label}`);
    process.exit(1);
  }
  const elapsed = ((Date.now() - start) / 1000).toFixed(2);
  console.log(`<<< Done: ${label} in ${elapsed}s`);
}

timed('Type check', 'npx tsc --noEmit');
timed('Next.js build', 'npx next build');

Knowledge Check: Turbopack Loaders vs Webpack Loaders

Test your understanding of the key difference between Turbopack's loader system and Webpack's loader system in Next.js 15.

Lesson Recap: Turbopack and Compiler Configuration

In this lesson you explored the full compiler and bundler configuration stack in Next.js 15:

  • Turbopack architecture — incremental computation, parallel Rust workers, and persistent disk caching make it dramatically faster than Webpack for development workflows.
  • turbopack config block — use rules for file-level transforms, resolveAlias for module path shortcuts, and keep tsconfig.json paths in sync to avoid type/bundle mismatches.
  • SWC as the transformer — distinct from Turbopack (the bundler), SWC handles TS stripping, JSX, and minification. A .babelrc in your project silently disables SWC.
  • compiler options — removeConsole, reactRemoveProperties, and CSS-in-JS plugins are configured at the top-level compiler key, not inside turbopack.
  • Bundle analysis — use @next/bundle-analyzer to visualize chunk composition and catch large dependencies or server-code leaking into client bundles.
  • optimizePackageImports — a zero-touch hint that enables tree-shaking for packages with poor ESM export maps.
  • CI caching — cache .next/cache between runs to leverage Turbopack's persistent cache and cut CI build times significantly.

The key mental model: Turbopack owns the graph, SWC owns the files, and next.config.ts is the single control plane for both.

Preguntas frecuentes

¿La lección «Análisis profundo de la configuración de Turbopack y del compilador» es gratis?

Sí — el texto completo de «Análisis profundo de la configuración de Turbopack y del compilador» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Next.js 15 Fullstack (App Router + Server Actions), actualiza a CoddyKit PRO. El curso de Next.js 15 Fullstack (App Router + Server Actions) incluye 4 lecciones en total.

¿Qué aprenderé en «Análisis profundo de la configuración de Turbopack y del compilador»?

Ajuste Turbopack, las transformaciones y el compilador basado en SWC para acelerar las compilaciones y reducir la salida. Practicas Next.js 15 Fullstack (App Router + Server Actions) con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Next.js 15 Fullstack (App Router + Server Actions)?

No se requiere experiencia previa. Next.js 15 Fullstack (App Router + Server Actions) en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.

¿Cuánto tiempo toma la lección «Análisis profundo de la configuración de Turbopack y del compilador»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Next.js 15 Fullstack (App Router + Server Actions)?

Sí. Cada lección de Next.js 15 Fullstack (App Router + Server Actions) incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Análisis y reducción del bundle del cliente
  2. Análisis profundo de la configuración de Turbopack y del compilador
  3. Límites de módulos con server-only y client-only
  4. Importaciones dinámicas, división de código e hidratación diferida
← Volver a Next.js 15 Fullstack (App Router + Server Actions)