Next.js Compiler and Turbopack

Understand how Next.js builds your code with Turbopack, SWC compiler options, and the React Compiler.

TL;DR

  1. Run next dev and next build, which both use Turbopack by default.
  2. Tune compile-time transforms with the compiler option in next.config.ts.
  3. Enable automatic memoization by setting reactCompiler: true in your config.

Turbopack

    next dev

    Use the plain commands, since Turbopack is already the default bundler.

    // package.json
    {
      "scripts": {
        "dev": "next dev",
        "build": "next build"
      }
    }
    --webpack

    Opt out of Turbopack when a project still depends on custom Webpack config.

    next dev --webpack
    next build --webpack
    File System Cache

    Reuse compiler work between runs with the on-disk cache, enabled by default.

    const nextConfig = {
      experimental: {
        turbopackFileSystemCacheForDev: true,
        turbopackFileSystemCacheForBuild: true,
      },
    };

Turbopack Config

    turbopack.rules

    Apply a Webpack-style loader to a file type, such as SVG files.

    const nextConfig = {
      turbopack: {
        rules: {
          '*.svg': {
            loaders: ['@svgr/webpack'],
            as: '*.js',
          },
        },
      },
    };
    turbopack.resolveAlias

    Swap one import for another across the whole project.

    const nextConfig = {
      turbopack: {
        resolveAlias: {
          underscore: 'lodash',
        },
      },
    };
    turbopack.resolveExtensions

    Change which file extensions are tried when an import has none.

    const nextConfig = {
      turbopack: {
        resolveExtensions: ['.mdx', '.tsx', '.ts', '.js'],
      },
    };

SWC Compiler Options

    removeConsole

    Strip console calls from the build while keeping error logging.

    const nextConfig = {
      compiler: {
        removeConsole: { exclude: ['error'] },
      },
    };
    styledComponents

    Enable server rendering and readable class names for styled-components.

    const nextConfig = {
      compiler: {
        styledComponents: true,
      },
    };
    reactRemoveProperties

    Remove test attributes such as data-testid from production markup.

    const nextConfig = {
      compiler: {
        reactRemoveProperties: true,
      },
    };

React Compiler

    babel-plugin-react-compiler

    Install the compiler plugin as a dev dependency before enabling it.

    npm install -D babel-plugin-react-compiler
    reactCompiler

    Turn on automatic memoization for every component in the app.

    import type { NextConfig } from 'next';
    
    const nextConfig: NextConfig = {
      reactCompiler: true,
    };
    
    export default nextConfig;
    Less Manual Memo

    Write plain code and let the compiler decide what to memoize.

    // Before: manual memoization
    const total = useMemo(() => sum(items), [items]);
    
    // After: the compiler handles it
    const total = sum(items);
    'use no memo'

    Opt a single component out when the compiler causes a problem.

    function LegacyWidget() {
      'use no memo';
      return <OldChart />;
    }

Tips

  1. Move custom Webpack loaders into turbopack.rules, so your project can stay on the default bundler.
  2. Use compiler.removeConsole in production builds to strip debug logging without touching any of your source files.

Warnings

  1. A custom webpack function in next.config.ts makes next build fail in Next.js 16 unless you pass --webpack.
  2. A babel.config.js file adds a Babel pass to every build, which slows compilation, so remove it unless you need it.

In Practice

FAQ