---
title: "Webpack Configuration"
description: "Next.js coordinates its build pipeline and development server by dynamically constructing compiler options Build Pipeline, Hot Reloading. The Webpack configuration system assembles specialized comp..."
last_updated: "2026-10-12T06:38:56.85659+00:00"
canonical_url: "https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/webpack-configuration"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [packages/next/src/build/webpack-config.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-config.ts)
- [packages/next/next-runtime.webpack-config.js](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/next-runtime.webpack-config.js)
- [packages/next/src/server/dev/hot-reloader-webpack.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/server/dev/hot-reloader-webpack.ts)
- [packages/next/src/build/webpack-build/impl.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/impl.ts)
- [packages/next/taskfile.js](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/taskfile.js)
- [packages/next/src/build/webpack/config/index.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/index.ts)
- [packages/next/src/build/webpack/config/blocks/base.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/blocks/base.ts)
- [packages/next/src/build/entries.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts)
- [packages/next/next-devtools.webpack-config.js](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/next-devtools.webpack-config.js)
- [packages/next/src/build/webpack-build/index.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/index.ts)
- [packages/next/src/build/webpack/plugins/middleware-plugin.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/plugins/middleware-plugin.ts)
- [packages/next/src/bundles/webpack/packages/webpack.js](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/bundles/webpack/packages/webpack.js)
- [packages/next/src/build/webpack/config/utils.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/utils.ts)
- [packages/next/src/bundles/webpack/packages/package.js](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/bundles/webpack/packages/package.js)
- [packages/next/src/server/config-utils.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/server/config-utils.ts)
- [packages/next/src/bundles/webpack/packages/sources.js](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/bundles/webpack/packages/sources.js)
- [packages/next/src/build/create-compiler-aliases.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/create-compiler-aliases.ts)
- [packages/next/src/build/webpack/config/blocks/css/index.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/blocks/css/index.ts)
- [packages/next/src/build/output/log.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/output/log.ts)
- [packages/next/src/build/webpack/config/blocks/css/loaders/client.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/blocks/css/loaders/client.ts)
- [packages/next/src/build/webpack/config/blocks/css/loaders/next-font.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/blocks/css/loaders/next-font.ts)
- [packages/next/src/server/lib/lru-cache.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/server/lib/lru-cache.ts)
- [packages/next/src/shared/lib/get-rspack.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/shared/lib/get-rspack.ts)
</details>

## Overview

Next.js coordinates its build pipeline and [development server](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/development/development-server) by dynamically constructing compiler options [Build Pipeline](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/build-pipeline), [Hot Reloading](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/development/hot-reloading). The Webpack configuration system assembles specialized compilation targets across the browser client, Node.js server, and [Edge Runtime](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/server-runtime/edge-runtime) environments Webpack Configuration. By chaining functional configuration blocks[Webpack Configuration](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/webpack-configuration), it integrates [SWC Compiler](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/swc-compiler) transformations [Webpack Loaders](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/webpack-loaders), asset handling, and module aliasing Webpack Configuration. Adjacent manifest plugins and runtime builders consume these configuration outputs to generate application bundles, route loaders, and runtime artifacts [Manifest Plugins](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/manifest-plugins), [Route Discovery](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/route-discovery).

Sources: [packages/next/src/build/webpack/config/index.ts:10-50](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/index.ts#L10-L50), [packages/next/src/build/webpack-config.ts:985-1007](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-config.ts#L985-L1007)

## Compiler target architecture

### Compiler Environment Matrix

Next.js implements a multi-target compilation model that separates builds across three distinct environments: the Node.js server, the Edge Runtime server, and the browser client. During production compilation (`webpackBuild`), these targets are orchestrated sequentially or via worker threads in an ordered pipeline: `server`, `edge-server`, and `client`. Running the server compilers before the client compiler allows Next.js to track server/client component boundaries and dynamically inject client-side entry points discovered during server compilation.

```mermaid
flowchart TD
    S["Server Compiler (Node.js)"] --> ES["Edge Server Compiler (Edge Runtime)"]
    ES --> IC["Inject Client Entries"]
    IC --> C["Client Compiler (Browser)"]
```
Sources: [packages/next/src/build/webpack-build/index.ts:14-18](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/index.ts#L14-L18), [packages/next/src/build/webpack-build/impl.ts:246-298](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/impl.ts#L246-L298)

| Compiler Name | Target Environment | Key Configuration & External Handling |
| :--- | :--- | :--- |
| `server` | Node.js Server | Presets node externals, applies `handleExternals` resolver, strips Node built-ins and Bun identifiers. |
| `edge-server` | Edge Runtime | Configures edge polyfilled modules, party town fallbacks, and `handleWebpackExternalForEdgeRuntime`. |
| `client` | Browser Client | Bundles React and user code for browser execution, registers React Refresh and telemetry plugins. |

Sources: [packages/next/src/build/webpack-config.ts:987-1063](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-config.ts#L987-L1063), [packages/next/src/build/webpack-build/impl.ts:175-203](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/impl.ts#L175-L203)

> [!NOTE]
> Server compilations execute prior to the client bundle so that client component entry points discovered via `pluginState.injectedClientEntries` can be accurately fed into the client compiler configuration.
Sources: [packages/next/src/build/webpack-build/impl.ts:232-288](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/impl.ts#L232-L288)

## Base configuration composition

### Functional Pipeline Assembly

The construction of a Webpack configuration in Next.js is orchestrated by `buildConfiguration`, an asynchronous function that instantiates a `ConfigurationContext` object and pipes the initial `webpack.Configuration` through an array of functional blocks Webpack Configuration. The context encapsulates configuration flags such as `hasAppDir`, `isDevelopment`, `isServer`, `isEdgeRuntime`, `targetWeb`, `rootDirectory`, `transpilePackages`, and `experimental` features Webpack Configuration.

```mermaid
flowchart TD
    BC["buildConfiguration"] --> CTX["Initialize ConfigurationContext"]
    CTX --> FNS["Assemble Block Functions (base, css, images)"]
    FNS --> PIPE["Execute pipe(...fns)"]
    PIPE --> OUT["Return webpack.Configuration"]
```
Sources: [packages/next/src/build/webpack/config/index.ts:10-82](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/index.ts#L10-L82)

The pipeline uses a utility function `pipe` that reduces an array of configuration modifier functions sequentially, supporting both synchronous and asynchronous operations Webpack Configuration. By default, `buildConfiguration` incorporates the `base` block and the `css` block, and conditionally appends the `images` block unless `disableStaticImages` is explicitly enabled Webpack Configuration.

| Function / Utility | File Path | Purpose |
| :--- | :--- | :--- |
| `buildConfiguration` | `packages/next/src/build/webpack/config/index.ts` | Main entry point coordinating context setup and functional block piping. |
| `pipe` | `packages/next/src/build/webpack/config/utils.ts` | Asynchronous function reducer executing configuration transforms in sequence. |
| `base` | `packages/next/src/build/webpack/config/blocks/base.ts` | Curried block configuring mode, target, devtool, and source map plugins. |

Sources: [packages/next/src/build/webpack/config/index.ts:10-82](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/index.ts#L10-L82), [packages/next/src/build/webpack/config/utils.ts:40-46](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/utils.ts#L40-L46), [packages/next/src/build/webpack/config/blocks/base.ts:19-22](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/blocks/base.ts#L19-L22)

> [!NOTE]
> The `assetPrefix` value normalized inside `ConfigurationContext` automatically strips any trailing slash from the provided input string to maintain consistent asset URL resolution across compilation targets.
Sources: [packages/next/src/build/webpack/config/index.ts:62-66](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/index.ts#L62-L66)

### Base Configuration Block & Source Map Strategy

The `base` configuration block, curried using `lodash.curry`, assigns fundamental Webpack properties based on the `ConfigurationContext` Webpack Configuration. It sets `config.mode` to `'development'` or `'production'` and determines `config.name` using constants from `COMPILER_NAMES` (`server`, `edgeServer`, or client) Webpack Configuration. For non-web targets, it specifies `node18.17`, aligning with the engine version defined in `packages/next/package.json` Webpack Configuration.

Source map generation within the `base` block adapts dynamically depending on development mode, runtime environment, and experimental flags Webpack Configuration.

| Condition | `config.devtool` Setting | Associated Plugin / Behavior |
| :--- | :--- | :--- |
| `ctx.isDevelopment` | `'eval-source-map'` (Webpack) / Forked plugin (Rspack) | Full-fidelity source maps with original variable names and columns for browser debugging. |
| `ctx.isEdgeRuntime` (Production) | `'source-map'` | Standard source map generation for edge runtime bundles. |
| `ctx.isServer && ctx.serverSourceMaps` (Production) | `'source-map'` | Enabled when server source maps are explicitly requested in configuration. |
| `ctx.productionBrowserSourceMaps && ctx.isClient` (Production) | `'source-map'` | Generates browser source maps for client production builds. |
| Default Production (Fallback) | `false` | Disables source map generation to reduce bundle size and compile overhead. |

Sources: [packages/next/src/build/webpack/config/blocks/base.ts:36-54](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/blocks/base.ts#L36-L54)

> [!WARNING]
> When `eval-source-map` is active under Rspack or Webpack, the block resets `config.devtool` to `false` and explicitly injects either `EvalSourceMapDevToolPlugin` or `getRspackCore().EvalSourceMapDevToolPlugin` alongside `DevToolsIgnorePlugin` using path-ignoring rules.
Sources: [packages/next/src/build/webpack/config/blocks/base.ts:67-86](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/blocks/base.ts#L67-L86)

## Module aliasing and resolution

### Custom Module Aliases and Path Resolution

Next.js sets up comprehensive compiler aliases via `createWebpackAliases` to map project roots, page directories, app directories, and internal framework assets. During development, custom application and error pages (`_app`, `_error`, `_document`) are resolved via array aliases that fall back to internal Next.js default templates if the user files are absent.

```typescript
if (dev) {
  const nextDistPath = 'next/dist/' + (isEdgeServer ? 'esm/' : '')
  customAppAliases[`${PAGES_DIR_ALIAS}/_app`] = [
    ...(pagesDir
      ? pageExtensions.reduce((prev, ext) => {
          prev.push(path.join(pagesDir, `_app.${ext}`))
          return prev
        }, [] as string[])
      : []),
    `${nextDistPath}pages/_app.js`,
  ]
  customAppAliases[`${PAGES_DIR_ALIAS}/_error`] = [
    ...(pagesDir
      ? pageExtensions.reduce((prev, ext) => {
          prev.push(path.join(pagesDir, `_error.${ext}`))
          return prev
        }, [] as string[])
      : []),
    `${nextDistPath}pages/_error.js`,
  ]
  customDocumentAliases[`${PAGES_DIR_ALIAS}/_document`] = [
    ...(pagesDir
      ? pageExtensions.reduce((prev, ext) => {
          prev.push(path.join(pagesDir, `_document.${ext}`))
          return prev
        }, [] as string[])
      : []),
    `${nextDistPath}pages/_document.js`,
  ]
}
```
Sources: [packages/next/src/build/create-compiler-aliases.ts:73-102](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/create-compiler-aliases.ts#L73-L102)

Client compilers map the instrumentation stub (`private-next-instrumentation-client`) to `INSTRUMENTATION_CLIENT_STUB_PATH`, and resolve user instrumentation through `private-next-instrumentation-client-user` with a fallback to `private-next-empty-module` (which is configured as `false` to create a Webpack no-op module). 

| Alias Constant / Key | Target Path / Resolution Behavior |
| :--- | :--- |
| `@vercel/og$` | `next/dist/server/og/image-response` |
| `next/dist/server/ReactDOMServerPages` | `react-dom/server.edge` (React 19) or `react-dom/server.browser` (React 18) |
| `styled-jsx/style$` | `defaultOverrides['styled-jsx/style']` |
| `PAGES_DIR_ALIAS` | User-defined pages directory (if present) |
| `APP_DIR_ALIAS` | User-defined app directory (if present) |
| `ROOT_DIR_ALIAS` | Absolute path to project root (`dir`) |
| `DOT_NEXT_ALIAS` | Build output directory (`distDir`) |
| `setimmediate` | `next/dist/compiled/setimmediate` |

Sources: [packages/next/src/build/create-compiler-aliases.ts:105-252](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/create-compiler-aliases.ts#L105-L252)

> [!NOTE]
> In browser bundles, `createWebpackAliases` iterates over `browserVariantModules` (generated from the filesystem) and maps every `.js` file under `NEXT_PROJECT_ROOT_DIST` to its `.browser` sibling to prevent server-only logic from leaking into client bundles.
Sources: [packages/next/src/build/create-compiler-aliases.ts:176-187](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/create-compiler-aliases.ts#L176-L187)

### Vendored React Runtimes and Layer Mapping

Next.js vendors its own React channels and maps `react`, `react-dom`, and `react-server-dom-webpack` depending on the target environment condition (`browser`, `edge`, or `nodejs`) and React condition (`client` or `server`). The function `createVendoredReactAliases` builds these mappings based on the active `bundledReactChannel` ('' or '-experimental') and layer constraints.

```typescript
export function createVendoredReactAliases(
  bundledReactChannel: BundledReactChannel,
  {
    layer,
    isBrowser,
    isEdgeServer,
    reactProductionProfiling,
  }: {
    layer: WebpackLayerName
    isBrowser: boolean
    isEdgeServer: boolean
    reactProductionProfiling: boolean
  }
): CompilerAliases {
  const environmentCondition = isBrowser
    ? 'browser'
    : isEdgeServer
      ? 'edge'
      : 'nodejs'
  const reactCondition = shouldUseReactServerCondition(layer)
    ? 'server'
    : 'client'

  // ✅ Correct alias
```
Sources: [packages/next/src/build/create-compiler-aliases.ts:377-400](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/create-compiler-aliases.ts#L377-L400)

Server-only and client-only import guards are enforced via `createServerOnlyClientOnlyAliases`, which substitutes restricted packages with empty modules or compilation errors depending on whether the compiler runs on the server or client.

| Module Request | Server Target Resolution | Client Target Resolution |
| :--- | :--- | :--- |
| `server-only$` | `next/dist/compiled/server-only/empty` | `next/dist/compiled/server-only/index` |
| `client-only$` | `next/dist/compiled/client-only/error` | `next/dist/compiled/client-only/index` |
| `next/dist/compiled/server-only$` | `next/dist/compiled/server-only/empty` | `next/dist/compiled/server-only/index` |
| `next/dist/compiled/client-only$` | `next/dist/compiled/client-only/error` | `next/dist/compiled/client-only/index` |

Sources: [packages/next/src/build/create-compiler-aliases.ts:254-274](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/create-compiler-aliases.ts#L254-L274)

> [!WARNING]
> If `serverExternalPackages` and `transpilePackages` contain overlapping package names, Webpack configuration initialization throws an error to prevent conflicting externalization and transpilation rules.
Sources: [packages/next/src/build/webpack-config.ts:883-894](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-config.ts#L883-L894)

## Style processing and font loaders

### CSS Loader Pipelines and PostCSS Integration

The CSS configuration block processes style sheets via modular loader pipelines, supporting global CSS, CSS modules, Sass variants (`.scss`, `.sass`), and [font optimization](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/built-in-features/font-optimization). The core function `css` handles rule generation using curried configuration pipelines. Sass files are preprocessed by `sass-loader`, which compiles proprietary syntax and passes through CSS imports with `sourceMap: true`, followed by `resolve-url-loader` to rewrite relative paths. PostCSS transformations are initialized lazily via `lazyPostCSS`, attaching legacy plugin compatibility and vendor helpers (`postcss.vendor.prefix` and `postcss.vendor.unprefixed`).

```typescript
export async function lazyPostCSS(
  rootDirectory: string,
  supportedBrowsers: string[] | undefined,
  disablePostcssPresetEnv: boolean | undefined,
  useLightningcss: boolean | undefined
) {
  if (!postcssInstancePromise) {
    postcssInstancePromise = (async () => {
      const postcss = require('postcss') as typeof import('postcss').default
      // @ts-ignore backwards compat
      postcss.plugin = function postcssPlugin(name, initializer) {
        function creator(...args: any) {
          let transformer = initializer(...args)
          transformer.postcssPlugin = name
          // transformer.postcssVersion = new Processor().version
          return transformer
        }

        let cache: any
        Object.defineProperty(creator, 'postcss', {
          get() {
            if (!cache) cache = creator()
            return cache
          },
        })

        creator.process = function (
          css: any,
          processOpts: any,
          pluginOpts: any
        ) {
          return postcss([creator(pluginOpts)]).process(css, processOpts)
        }

        return creator
      }

      // @ts-ignore backwards compat
      postcss.vendor = {
        /**
         * Returns the vendor prefix extracted from an input string.
         *
         * @example
         * postcss.vendor.prefix('-moz-tab-size') //=> '-moz-'
         * postcss.vendor.prefix('tab-size')      //=> ''
         */
        prefix: function prefix(prop: string): string {
          const match = prop.match(/^(-\w+-)/)

          if (match) {
            return match[0]
          }

          return ''
        },

        /**
         * Returns the input string stripped of its vendor prefix.
         *
         * @example
         * postcss.vendor.unprefixed('-moz-tab-size') //=> 'tab-size'
         */
        unprefixed: function unprefixed(
          /**
           * String with or without vendor prefix.
           */
          prop: string
        ): string {
          return prop.replace(/^-\w+-/, '')
        },
      }
```
Sources: [packages/next/src/build/webpack/config/blocks/css/index.ts:58-128](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/blocks/css/index.ts#L58-L128)

Client-side style loading delegates to `getClientStyleLoader`, which inspects environment flags to determine whether to inject development style tags or production chunk extracts.

| Environment / Target Condition | Loader Used | Loader Options / Insertion Behavior |
| :--- | :--- | :--- |
| Development (`pages/` directory) | `next-style-loader` | Inserts style elements directly before the DOM anchor element `#__next_css__DO_NOT_USE__` inside `<head>` |
| Production or App Directory (`isDevelopment: false` or `shouldEnableApp: true`) | `MiniCssExtractPlugin.loader` | Sets `publicPath` to `${assetPrefix}/_next/` (or `/` if `experimentalInlineCss` is active) and `esModule: false` |

Sources: [packages/next/src/build/webpack/config/blocks/css/loaders/client.ts:4-60](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/blocks/css/loaders/client.ts#L4-L60)

> [!NOTE]
> `MiniCssExtractPlugin` disables ordering warnings (`ignoreOrder: true`) because Next.js guarantees safe CSS code-splitting through strict module scoping and single entrypoint global CSS constraints.
Sources: packages/next/src/build/webpack/config/blocks/css/index.ts:589-617

### Rspack Core Checks and Font Extraction

When executing builds with Rspack (`NEXT_RSPACK`), style extraction utilizes Rspack's internal CSS plugin architecture. The resolution helper `getRspackCore` checks availability and logs experimental notices using a deduplicated LRU warning cache.

```typescript
export function getRspackCore() {
  warnRspack()
  try {
    // eslint-disable-next-line @next/internal/typechecked-require
    return require('next-rspack/rspack-core')
  } catch (e) {
    if (e instanceof Error && 'code' in e && e.code === 'MODULE_NOT_FOUND') {
      throw new Error(
        '@rspack/core is not available. Please make sure `next-rspack` is correctly installed.'
      )
    }

    throw e
  }
}
```
Sources: [packages/next/src/shared/lib/get-rspack.ts:3-17](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/shared/lib/get-rspack.ts#L3-L17)

Font extraction rules match target files against Google and local font loader definitions, running `getNextFontLoader` to configure `css-loader` in `pure` mode alongside `next-font-loader`.

```typescript
export function getNextFontLoader(
  ctx: ConfigurationContext,
  postcss: any,
  fontLoaderPath: string
): webpack.RuleSetUseItem[] {
  const loaders: webpack.RuleSetUseItem[] = []

  if (ctx.isClient) {
    // Add appropriate development mode or production mode style
    // loader
    loaders.push(
      getClientStyleLoader({
        hasAppDir: ctx.hasAppDir,
        isDevelopment: ctx.isDevelopment,
        assetPrefix: ctx.assetPrefix,
      })
    )
  }

  loaders.push({
    loader: require.resolve('../../../../loaders/css-loader/src'),
    options: {
      postcss,
      importLoaders: 1,
      // Use CJS mode for backwards compatibility:
      esModule: false,
      url: (url: string, resourcePath: string) =>
        cssFileResolve(url, resourcePath, ctx.experimental.urlImports),
      import: (url: string, _: any, resourcePath: string) =>
        cssFileResolve(url, resourcePath, ctx.experimental.urlImports),
      modules: {
        // Do not transform class names (CJS mode backwards compatibility):
        exportLocalsConvention: 'asIs',
        // Server-side (Node.js) rendering support:
        exportOnlyLocals: ctx.isServer,
        // Disallow global style exports so we can code-split CSS and
        // not worry about loading order.
        mode: 'pure',
        getLocalIdent: (
          _context: any,
          _localIdentName: any,
          exportName: string,
          _options: any,
          meta: any
        ) => {
          // hash from next-font-loader
          return `__${exportName}_${meta.fontFamilyHash}`
        },
      },
      fontLoader: true,
    },
  })

  loaders.push({
    loader: 'next-font-loader',
    options: {
      isDev: ctx.isDevelopment,
      isServer: ctx.isServer,
      assetPrefix: ctx.assetPrefix,
      deploymentId: ctx.deploymentId,
      fontLoaderPath,
      postcss,
    },
  })

  return loaders
```
Sources: [packages/next/src/build/webpack/config/blocks/css/loaders/next-font.ts:6-71](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/blocks/css/loaders/next-font.ts#L6-L71)

The following call chain demonstrates how Rspack core checks emit deduplicated warnings during style and font loader initialization:

1. `css` calls `getNextFontLoader`
2. `getNextFontLoader` invokes `getClientStyleLoader`
3. `getClientStyleLoader` evaluates `getRspackCore`
4. `getRspackCore` executes `warnRspack`
5. `warnRspack` invokes `warnOnce`
6. `warnOnce` queries `has` on the internal LRU cache
7. If absent, `set` adds the warning key to `LRUNode` structures
8. `warn` delegates to `prefixedLog` to render console outputs

```typescript
export const css: (
  ctx: ConfigurationContext
) => (config: webpack.Configuration) => Promise<webpack.Configuration> = curry(
  async function css(ctx: ConfigurationContext, config: webpack.Configuration) {
```
Sources: [packages/next/src/build/webpack/config/blocks/css/index.ts:147-150](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/blocks/css/index.ts#L147-L150), [packages/next/src/build/webpack/config/blocks/css/loaders/next-font.ts:6-10](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/blocks/css/loaders/next-font.ts#L6-L10), [packages/next/src/build/webpack/config/blocks/css/loaders/client.ts:4-19](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/config/blocks/css/loaders/client.ts#L4-L19), [packages/next/src/shared/lib/get-rspack.ts:3-25](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/shared/lib/get-rspack.ts#L3-L25), [packages/next/src/build/output/log.ts:77-84](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/output/log.ts#L77-L84)

```mermaid
sequenceDiagram
    participant css as css
    participant nextFont as getNextFontLoader
    participant clientStyle as getClientStyleLoader
    participant rspackCore as getRspackCore
    participant warnRspack as warnRspack
    participant warnOnce as warnOnce
    participant lru as LRUCache
    participant log as prefixedLog

    css->>nextFont: Initialize font loader pipeline
    nextFont->>clientStyle: Get client style loader
    clientStyle->>rspackCore: Resolve Rspack core bindings
    rspackCore->>warnRspack: Trigger experimental Rspack notice
    warnRspack->>warnOnce: Check warning deduplication cache
    warnOnce->>lru: has(key) & set(key)
    warnOnce->>log: prefixedLog('warn', message)
```

> [!CAUTION]
> `calculateSize` functions passed to `LRUCache` must always return a positive integer greater than zero; returning zero causes unbounded cache growth because zero-size items are never evicted.
Sources: packages/next/src/server/lib/lru-cache.ts:130-135

## Edge Runtime module constraints

### Edge externals and polyfilled modules

For edge server compilation targets, Webpack configuration externally manages built-in packages and polyfills via custom external handlers and fallback definitions. Packages such as `@builder.io/partytown` and `next/dist/compiled/etag` resolve to empty objects (`{}`) to satisfy runtime requirements within lightweight V8 isolates.

```typescript
...(isEdgeServer
  ? [
      {
        '@builder.io/partytown': '{}',
        'next/dist/compiled/etag': '{}',
      },
      getEdgePolyfilledModules(),
      handleWebpackExternalForEdgeRuntime,
    ]
```
Sources: [packages/next/src/build/webpack-config.ts:997-1005](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-config.ts#L997-L1005)

> [!NOTE]
> Edge server configurations exclude standard Node.js built-in modules from direct bundling, routing them instead through `handleWebpackExternalForEdgeRuntime` and specialized polyfills.
Sources: packages/next/src/build/webpack-config.ts:987-1007

### Middleware plugin and unsupported Node APIs

The `MiddlewarePlugin` inspects module graphs and assets for Edge functions and middleware execution contexts. It enforces module constraints by checking usage against known edge-safe packages and tracking unsupported Node.js API usage.

```typescript
const KNOWN_SAFE_DYNAMIC_PACKAGES =
  require('../../../lib/known-edge-safe-packages.json') as string[]

```
Sources: [packages/next/src/build/webpack/plugins/middleware-plugin.ts:41-43](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/plugins/middleware-plugin.ts#L41-L43)

> [!WARNING]
> Importing restricted Node.js core modules into edge runtime files triggers build errors via static analysis and unsupported API detection routines.
Sources: packages/next/src/build/webpack/plugins/middleware-plugin.ts:14-16

## Internal tooling configurations

### Build-time runtime and devtools bundling

Next.js maintains dedicated configuration files (`next-runtime.webpack-config.js` and `next-devtools.webpack-config.js`) processed via task runner pipelines to compile internal runtimes, workers, and developer tools using Rspack core bindings and `@rspack/core`.

```javascript
const webpack = require('@rspack/core')
const path = require('path')
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const DevToolsIgnoreListPlugin = require('./webpack-plugins/devtools-ignore-list-plugin')
```
Sources: [packages/next/next-runtime.webpack-config.js:1-4](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/next-runtime.webpack-config.js#L1-L4)

```javascript
const path = require('path')
const webpack = require('@rspack/core')
const MODERN_BROWSERSLIST_TARGET = require('./src/shared/lib/modern-browserslist-target')
const DevToolsIgnoreListPlugin = require('./webpack-plugins/devtools-ignore-list-plugin')
```
Sources: [packages/next/next-devtools.webpack-config.js:1-4](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/next-devtools.webpack-config.js#L1-L4)

| Bundle Type | Entry Point Path | Output Directory | Target / Mode |
| :--- | :--- | :--- | :--- |
| `app-page` | `dist/esm/server/route-modules/app-page/module.js` | `dist/compiled/next-server` | `node` / dev or prod |
| `app-route` | `dist/esm/server/route-modules/app-route/module.js` | `dist/compiled/next-server` | `node` / dev or prod |
| `pages` | `dist/esm/server/route-modules/pages/module.js` | `dist/compiled/next-server` | `node` / dev or prod |
| `pages-api` | `dist/esm/server/route-modules/pages-api/module.js` | `dist/compiled/next-server` | `node` / dev or prod |
| `server` | `dist/esm/server/next-server.js` | `dist/compiled/next-server` | `node` / dev or prod |
| `use-cache-probe-worker` | `dist/esm/server/dev/use-cache-probe-worker.js` | `dist/compiled/next-server` | `node` / dev or prod |
| `dev-validation-worker` | `dist/esm/server/dev/dev-validation-worker.js` | `dist/compiled/next-server` | `node` / dev or prod |
| `next-devtools` | `src/next-devtools/entrypoint.ts` | `dist/compiled/next-devtools` | `browserslist` / dev or prod |

Sources: [packages/next/next-runtime.webpack-config.js:91-124](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/next-runtime.webpack-config.js#L91-L124), [packages/next/next-runtime.webpack-config.js:205-214](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/next-runtime.webpack-config.js#L205-L214), [packages/next/next-devtools.webpack-config.js:27-32](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/next-devtools.webpack-config.js#L27-L32)

> [!NOTE]
> The `app-worker` bundle category groups development validation and cache probe workers, dynamically resolving native SWC binding graphs from the installed runtime tree instead of bundling them under `dist/esm`.
Sources: packages/next/next-runtime.webpack-config.js:114-123, packages/next/next-runtime.webpack-config.js:160-172

### Webpack hook aliasing and local resolution

Build scripts load custom hook aliases via `loadWebpackHook` to intercept `webpack`, `webpack/package`, `webpack-sources`, and associated compiler components, redirecting requests to Next.js compiled versions unless custom user Webpack environments are requested via environment variables.

```typescript
export function loadWebpackHook(webpackProjectDir: string) {
  if (installed) {
    return
  }
  installed = true

  const requireHook =
    require('../server/require-hook') as typeof import('../server/require-hook')
  const customWebpack = Boolean(process.env.NEXT_PRIVATE_LOCAL_WEBPACK)
  if (customWebpack) {
```
Sources: [packages/next/src/server/config-utils.ts:3-12](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/server/config-utils.ts#L3-L12)

```typescript
const webpackAliases: [string, string][] = [
  ['webpack', 'next/dist/compiled/webpack/webpack-lib'],
  ['webpack/package', 'next/dist/compiled/webpack/package'],
  ['webpack/package.json', 'next/dist/compiled/webpack/package'],
  ['webpack/lib/webpack', 'next/dist/compiled/webpack/webpack-lib'],
  ['webpack/lib/webpack.js', 'next/dist/compiled/webpack/webpack-lib'],
  [
    'webpack/lib/node/NodeEnvironmentPlugin',
    'next/dist/compiled/webpack/NodeEnvironmentPlugin',
  ],
  [
    'webpack/lib/node/NodeEnvironmentPlugin.js',
    'next/dist/compiled/webpack/NodeEnvironmentPlugin',
  ],
  [
    'webpack/lib/BasicEvaluatedExpression',
    'next/dist/compiled/webpack/BasicEvaluatedExpression',
  ],
```
Sources: [packages/next/src/server/config-utils.ts:24-41](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/server/config-utils.ts#L24-L41)

> [!WARNING]
> Setting `NEXT_PRIVATE_LOCAL_WEBPACK` forces project-level module resolution for Webpack dependencies, triggering unrecoverable build errors if the target project lacks an installed `webpack` package in its dependencies.
Sources: packages/next/src/server/config-utils.ts:11-22

## Related

- [Build Pipeline](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/build-pipeline)
- [Webpack Loaders](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/webpack-loaders)
- [Manifest Plugins](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/manifest-plugins)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/llms.txt) for all pages in this wiki.
