---
title: "Build Pipeline"
description: "The build pipeline orchestrates the complete production compilation process for Next.js applications, transforming source files into optimized distribution bundles through CLI Commands, Route Disco..."
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/build-pipeline"
---

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

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

- [packages/next/src/build/index.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/index.ts)
- [packages/next/taskfile.js](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/taskfile.js)
- [packages/next/src/cli/next-build.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/cli/next-build.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/src/build/adapter/build-complete.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/adapter/build-complete.ts)
- [packages/next/src/build/turbopack-build/impl.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/turbopack-build/impl.ts)
- [packages/next/src/build/utils.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/utils.ts)
- [packages/next/src/build/type-check.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/type-check.ts)
- [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/bin/next.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/bin/next.ts)
- [packages/next/src/build/compiler.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/compiler.ts)
- [packages/next/src/build/entries.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts)
- [packages/next/src/build/worker.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/worker.ts)
</details>

## Overview

The build pipeline orchestrates the complete production compilation process for Next.js applications, transforming source files into optimized distribution bundles through [CLI Commands](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/cli-telemetry/cli-commands), [Route Discovery](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/route-discovery), and [Turbopack Engine](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/turbopack-engine). It coordinates static code verification, multi-target compilation, static analysis worker tasks, and output finalization while supporting both Webpack and [Turbopack Engine](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/turbopack-engine) backends.

Sources: [packages/next/src/build/index.ts:188-196](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/index.ts#L188-L196), [packages/next/src/cli/next-build.ts:6-19](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/cli/next-build.ts#L6-L19), [packages/next/src/build/turbopack-build/impl.ts:25-30](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/turbopack-build/impl.ts#L25-L30)

## Build Pipeline Lifecycle and Orchestration

### Setup Tasks and Environment Initialization

The `next build` command initializes execution by loading exception listeners and environment configuration files via `@next/env` [packages/next/src/build/index.ts:17-20](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/index.ts#L17-L20). SWC bindings and lockfile patch promises are initialized alongside memory management checks for available write access and directory structures [packages/next/src/build/index.ts:165-166](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/index.ts#L165-L166). The build process installs required native compiler bindings, establishes tracing spans, and sets up global build contexts (`NextBuildContext`) before configuration loading [packages/next/src/build/index.ts:166-189](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/index.ts#L166-L189).

```mermaid
flowchart TD
    A["CLI Entry / next build"] --> B["Load Exception Listeners & Env Config"]
    B --> C["Install SWC Bindings & Lockfile Patches"]
    C --> D["Initialize NextBuildContext & Tracing Spans"]
    D --> E["Load & Validate NextConfigComplete"]
    E --> F["Detect Middleware, Proxy & Instrumentation Hooks"]
    F --> G["Route Discovery & Entry Mapping"]
```
Sources: [packages/next/src/build/index.ts:17-20](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/index.ts#L17-L20), [packages/next/src/build/index.ts:165-189](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/index.ts#L165-L189)

### Convention File Detection and Route Discovery

Root convention files such as middleware, proxy configurations, and instrumentation hooks are discovered by scanning the root directory against standard regular expressions [packages/next/src/build/index.ts:1469-1494](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/index.ts#L1469-L1494). The build pipeline checks for deprecated [Route Discovery](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/route-discovery) patterns and prevents conflicting concurrent declarations, throwing an error if both middleware and proxy files exist simultaneously [packages/next/src/build/index.ts:1521-1530](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/index.ts#L1521-L1530).

> [!WARNING]
> Detecting both `middleware` and `proxy` filename conventions simultaneously at the root level throws an immediate build error. Applications must migrate exclusively to `proxy` using `@next/codemod` [packages/next/src/build/index.ts:1521-1530](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/index.ts#L1521-L1530).

Sources: [packages/next/src/build/index.ts:1469-1494](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/index.ts#L1469-L1494), [packages/next/src/build/index.ts:1521-1530](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/index.ts#L1521-L1530)

## Type Checking and Static Verification

### Worker Execution and Implementation Selection

TypeScript setup and validation are delegated to a dedicated worker thread via `verifyAndRunTypeScript`, releasing compiler memory before compilation proceeds [packages/next/src/build/type-check.ts:13-21](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/type-check.ts#L13-L21). When type checking is enabled and the TypeScript CLI flag is inactive, the build pipeline instantiates a worker running `verify-typescript-setup` with exposed method `verifyAndRunTypeScriptInWorker` [packages/next/src/build/type-check.ts:45-57](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/type-check.ts#L45-L57). If `useTypeScriptCli` is enabled or checking is bypassed, execution falls back to in-process invocation [packages/next/src/build/type-check.ts:58-64](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/type-check.ts#L58-L64).

```typescript
typeCheckWorker = new Worker(
  require.resolve('../lib/verify-typescript-setup'),
  {
    exposedMethods: ['verifyAndRunTypeScriptInWorker'],
    debuggerPortOffset: -1,
    isolatedMemory: false,
    numWorkers: 1,
    enableWorkerThreads,
    maxRetries: 0,
  }
) as typeof typeCheckWorker
```
Sources: [packages/next/src/build/type-check.ts:46-56](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/type-check.ts#L46-L56)

> [!CAUTION]
> If a worker call encounters retry exhaustion (`Call retries were exceeded`), the build flushes telemetry and terminates with `process.exit(1)` rather than propagating internal Jest worker errors [packages/next/src/build/type-check.ts:185-193](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/type-check.ts#L185-L193).

Sources: [packages/next/src/build/type-check.ts:185-193](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/type-check.ts#L185-L193)

### Lifecycle and Telemetry Reporting

The `startTypeChecking` routine orchestrates the verification span (`run-typescript`), tracking check duration and reporting telemetry metrics upon completion [packages/next/src/build/type-check.ts:96-184](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/type-check.ts#L96-L184).

| Parameter / Metric | Source Field | Purpose |
| :--- | :--- | :--- |
| `durationInSeconds` | `typeCheckEnd[0]` | Duration of the type checking span in seconds |
| `typescriptVersion` | `verifyResult.version` | Resolved TypeScript compiler version |
| `inputFilesCount` | `verifyResult.result?.inputFilesCount` | Number of input files processed by the checker |
| `totalFilesCount` | `verifyResult.result?.totalFilesCount` | Total file count in the TypeScript project program |
| `incremental` | `verifyResult.result?.incremental` | Whether incremental compilation was utilized |
| `typeCheckMode` | `verifyResult.typeCheckMode` | Active mode utilized for type verification |

Sources: [packages/next/src/build/type-check.ts:173-183](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/type-check.ts#L173-L183)

## Entrypoint Creation and Route Mapping

### Compiler Entrypoint Generation and Mappings

The build pipeline creates compiler entrypoints by executing `createEntrypoints`, which processes mapped app paths, root paths, and pages to populate Webpack `EntryObject` tables for the `client`, `server`, and `edgeServer` compilers [packages/next/src/build/entries.ts:388-411](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L388-L411). Before processing individual page handlers, `createEntrypoints` normalizes catch-all routes and validates route matching coherence across `appPathsPerRoute` [packages/next/src/build/entries.ts:418-435](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L418-L435). When `config.experimental.strictRouteMatching` is enabled, the pipeline checks for missing canonical interception routes, incompatible parallel route slots, and unmatched app pages, throwing consolidated route-matching errors if inconsistencies are detected [packages/next/src/build/entries.ts:451-526](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L451-L526).

```typescript
const missingCanonicalInterceptionRoutes = config.experimental
  .strictRouteMatching
  ? findMissingCanonicalInterceptionRoutes(appPagePathsPerRoute)
  : []
const routeMatchingErrors: Error[] = []
if (missingCanonicalInterceptionRoutes.length > 0) {
  routeMatchingErrors.push(
    new MissingCanonicalInterceptionRoutesError(
      missingCanonicalInterceptionRoutes
    )
  )
}
if (incompatibleParallelRouteSlots.length > 0) {
  routeMatchingErrors.push(
    new IncompatibleParallelRouteSlotsError(
      await Promise.all(
        incompatibleParallelRouteSlots.map(async (incompatibleRoute) => {
          const layoutPagePath = posix.join(
            incompatibleRoute.layoutPath,
            'layout'
          )
          const layoutFile = await findPageFile(
            appDir,
            layoutPagePath,
            pageExtensions,
            true
          )

          return {
            ...incompatibleRoute,
            layoutFile: relative(
              rootDir,
              layoutFile
                ? join(appDir, layoutFile)
                : join(appDir, layoutPagePath)
            ),
          }
        })
      )
    )
  )
}
if (unmatchedAppPages.length > 0) {
  routeMatchingErrors.push(
    new UnmatchedAppPagesError(
      unmatchedAppPages.map((appPath) => {
        const absolutePagePath = appPageFiles.get(appPath)
        if (!absolutePagePath) return appPath

        return relative(
          rootDir,
          getPageFilePath({
            absolutePagePath,
            pagesDir,
            appDir,
            rootDir,
          })
        )
      })
    )
  )
}
if (routeMatchingErrors.length > 0) {
  const warning = getStrictRouteMatchingDefaultWarning(config)
  if (warning) {
    Log.warnOnce(warning)
  }
}
if (routeMatchingErrors.length === 1) {
  throw routeMatchingErrors[0]
}
if (routeMatchingErrors.length > 1) {
  throw new Error(
    routeMatchingErrors.map((error) => error.message).join('\n\n')
  )
}
```
Sources: [packages/next/src/build/entries.ts:451-526](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L451-L526)

> [!WARNING]
> Mismatched parallel route slots or missing canonical interception routes during strict route matching will cause the build pipeline to throw validation errors immediately before entrypoints are compiled [packages/next/src/build/entries.ts:451-526](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L451-L526).

Sources: [packages/next/src/build/entries.ts:451-526](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L451-L526)

### Runtime Selection and Loader Routing

The runtime target and loader configuration for a given page are determined by evaluating file types, runtimes, and page types through `runDependingOnPageType` and specific builder helpers [packages/next/src/build/entries.ts:322-386](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L322-L386). Depending on whether a route belongs to the Pages router, [App router](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/client-runtime/app-router), API [route handlers](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/server-runtime/route-handlers), instrumentation hooks, or middleware, the pipeline selects the appropriate compilation strategy.

| Page / File Type | Condition | Target Runtimes / Handlers |
| :--- | :--- | :--- |
| Root Instrumentation Hook | `pageType === PAGE_TYPES.ROOT && isInstrumentationHookFile(page)` | Server and Edge Server [packages/next/src/build/entries.ts:330-337](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L330-L337) |
| Proxy File | `isProxyFile(page)` | Server (Node.js) [packages/next/src/build/entries.ts:339-342](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L339-L342) |
| Middleware File | `isMiddlewareFile(page)` | Server (if `nodejs` runtime) or Edge Server [packages/next/src/build/entries.ts:344-352](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L344-L352) |
| API Route | `isAPIRoute(page)` | Edge Server (if [Edge runtime](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/server-runtime/edge-runtime)) or Server [packages/next/src/build/entries.ts:354-362](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L354-L362) |
| Document Page | `page === '/_document'` | Server (Node.js) [packages/next/src/build/entries.ts:363-366](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L363-L366) |
| Core App Pages (`_app`, `_error`, `404`, `500`) | `page === '/_app' \|\| page === '/_error' \|\| page === '/404' \|\| page === '/500'` | Client and Server [packages/next/src/build/entries.ts:367-376](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L367-L376) |
| Edge Runtime Page | `isEdgeRuntime(pageRuntime)` | Client and Edge Server [packages/next/src/build/entries.ts:377-381](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L377-L381) |

Sources: [packages/next/src/build/entries.ts:322-386](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L322-L386)

> [!TIP]
> When `edgeServer.instrumentation` is the sole entry in the edge server object, the build pipeline removes the redundant edge instrumentation entry since instrumentation can execute purely on the Node.js server [packages/next/src/build/entries.ts:798-803](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L798-L803).

Sources: [packages/next/src/build/entries.ts:798-803](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L798-L803)

### Entrypoint Finalization and Webpack Layers

Once initial entry objects are assembled, `finalizeEntrypoint` assigns the required [webpack configuration](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/webpack-configuration) layers (`layer`), runtimes (`runtime`), and chunking parameters based on the active `compilerType` (`server`, `edgeServer`, or `client`) [packages/next/src/build/entries.ts:813-915](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L813-L915). For server-side entries, API routes are assigned `WEBPACK_LAYERS.apiNode`, instrumentation hooks map to `WEBPACK_LAYERS.instrument`, and React Server Components map to `WEBPACK_LAYERS.reactServerComponents` [packages/next/src/build/entries.ts:835-852](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L835-L852). Edge server entries are configured with `EDGE_RUNTIME_WEBPACK` runtime, assignment library structures (`_ENTRIES`), and disabled async chunks (`asyncChunks: false`) [packages/next/src/build/entries.ts:853-867](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L853-L867). Client entries configure dependency relationships (`dependOn`) pointing to runtime chunks such as `CLIENT_STATIC_FILES_RUNTIME_MAIN` or `CLIENT_STATIC_FILES_RUNTIME_MAIN_APP` [packages/next/src/build/entries.ts:868-911](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L868-L911).

```typescript
switch (compilerType) {
  case COMPILER_NAMES.server: {
    const layer = isApi
      ? WEBPACK_LAYERS.apiNode
      : isInstrumentation
        ? WEBPACK_LAYERS.instrument
        : isServerComponent
          ? WEBPACK_LAYERS.reactServerComponents
          : name.startsWith('pages/')
            ? WEBPACK_LAYERS.pagesDirNode
            : undefined

    return {
      publicPath: isApi ? '' : undefined,
      runtime: isApi ? 'webpack-api-runtime' : 'webpack-runtime',
      layer,
      ...entry,
    }
  }
  case COMPILER_NAMES.edgeServer: {
    return {
      layer: isApi
        ? WEBPACK_LAYERS.apiEdge
        : isMiddlewareFilename(name) || isInstrumentation
          ? WEBPACK_LAYERS.middleware
          : name.startsWith('pages/')
            ? WEBPACK_LAYERS.pagesDirEdge
            : undefined,
      library: { name: ['_ENTRIES', `middleware_[name]`], type: 'assign' },
      runtime: EDGE_RUNTIME_WEBPACK,
      asyncChunks: false,
      ...entry,
    }
  }
```
Sources: [packages/next/src/build/entries.ts:834-867](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/entries.ts#L834-L867)

## Webpack Production Compilation Execution

### Worker-Dispatched Compilation and Sequencing

Production bundling delegates compilation tasks to isolated worker threads or executes them synchronously based on configuration flags [packages/next/src/build/webpack-build/index.ts:131-163](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/index.ts#L131-L163). When worker isolation is enabled via `webpackBuildWithWorker`, the build pipeline processes compilers sequentially in a predefined order: `server`, `edge-server`, and `client` [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-18), [packages/next/src/build/webpack-build/index.ts:34-121](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/index.ts#L34-L121). Each compiler runs inside a separate worker process initialized with serialized build contexts, trace states, and telemetry instances [packages/next/src/build/webpack-build/impl.ts:405-437](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/impl.ts#L405-L437). 

```mermaid
sequenceDiagram
    participant Main as webpackBuildWithWorker
    participant Worker as Worker Thread (impl.ts)
    participant Server as Server Compiler
    participant Client as Client Compiler

    Main->>Worker: workerMain(compilerName: "server")
    Worker->>Server: runCompiler(serverConfig)
    Server-->>Worker: serverResult, inputFileSystem
    Worker-->>Main: CompilerResult & pluginState
    Main->>Main: Merge pluginState & injected client entries
    Main->>Worker: workerMain(compilerName: "client")
    Worker->>Client: runCompiler(clientConfig)
    Client-->>Worker: clientResult, inputFileSystem
    Worker-->>Main: CompilerResult & telemetryState
```
Sources: [packages/next/src/build/webpack-build/impl.ts:246-299](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/impl.ts#L246-L299), [packages/next/src/build/webpack-build/index.ts:34-121](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/index.ts#L34-L121)

> [!WARNING]
> Server compilers must execute before the client compiler so that client component boundaries discovered during server rendering are injected into the client entry configuration via `pluginState.injectedClientEntries` [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).

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)

### Compiler Execution and Lifecycle Handling

The low-level compiler runner initializes the bundler via `getWebpackBundler()`, preserves file system caching instances (`inputFileSystem`), tracks `fsStartTime`, and guarantees that compilers are properly closed upon completion [packages/next/src/build/compiler.ts:39-92](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/compiler.ts#L39-L92). 

| Function / Helper | File Path | Purpose |
| :--- | :--- | :--- |
| `runCompiler` | `packages/next/src/build/compiler.ts` | Executes a Webpack configuration, manages file system bindings, and coordinates compiler closure [packages/next/src/build/compiler.ts:39-92](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/compiler.ts#L39-L92) |
| `closeCompiler` | `packages/next/src/build/compiler.ts` | Invokes Webpack 5 `compiler.close()` to flush persistent caches [packages/next/src/build/compiler.ts:32-37](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/compiler.ts#L32-L37) |
| `generateStats` | `packages/next/src/build/compiler.ts` | Extracts errors, warnings, and module traces from compilation stats objects [packages/next/src/build/compiler.ts:11-28](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/compiler.ts#L11-L28) |
| `webpackBuildImpl` | `packages/next/src/build/webpack-build/impl.ts` | Orchestrates entry point generation, compiler runs, message formatting, and error throwing [packages/next/src/build/webpack-build/impl.ts:73-402](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/impl.ts#L73-402) |

Sources: [packages/next/src/build/compiler.ts:11-92](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/compiler.ts#L11-L92), [packages/next/src/build/webpack-build/impl.ts:73-402](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/impl.ts#L73-L402)]

> [!NOTE]
> Webpack 5 requires compilers to be explicitly closed to persist filesystem and memory caches correctly; `closeCompiler` checks for the presence of the `close` method for backwards compatibility [packages/next/src/build/compiler.ts:30-37](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/compiler.ts#L30-L37).

Sources: [packages/next/src/build/compiler.ts:30-37](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/compiler.ts#L30-L37)

### Error Formatting and Fatal Exit Codes

Post-compilation messages are formatted using `formatWebpackMessages`, and error thresholds determine whether the build terminates or proceeds [packages/next/src/build/webpack-build/impl.ts:324-401](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/impl.ts#L324-L401). If errors are encountered, the builder truncates output lists exceeding 5 entries to minimize noise and scans messages for specific diagnostic conditions [packages/next/src/build/webpack-build/impl.ts:338-377](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/impl.ts#L338-L377).

```typescript
if (
  error.indexOf('private-next-pages') > -1 &&
  error.indexOf('does not contain a default export') > -1
) {
  const page_name_regex = /'private-next-pages\/(?<page_name>[^']*)'/
  const parsed = page_name_regex.exec(error)
  const page_name = parsed && parsed.groups && parsed.groups.page_name
  throw new Error(
    `webpack build failed: found page without a React Component as default export in pages/${page_name}\n\nSee https://nextjs.org/docs/messages/page-without-valid-component for more info.`
  )
}

console.error(error)
console.error()

if (
  error.indexOf('private-next-pages') > -1 ||
  error.indexOf('__next_polyfill__') > -1
) {
  const err = new Error(
    'webpack config.resolve.alias was incorrectly overridden. https://nextjs.org/docs/messages/invalid-resolve-alias'
  ) as NextError
  err.code = 'INVALID_RESOLVE_ALIAS'
  throw err
}
const err = new Error(
  `Build failed because of ${process.env.NEXT_RSPACK ? 'Rspack' : 'webpack'} errors`
) as NextError
err.code = 'WEBPACK_ERRORS'
throw err
```
Sources: [packages/next/src/build/webpack-build/impl.ts:348-377](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-build/impl.ts#L348-L377)

## Static Analysis and Worker Tasks

### Worker Environment Initialization and Task Dispatch

Next.js offloads heavy static analysis tasks, such as determining page static rendering properties, to isolated worker threads via `packages/next/src/build/worker.ts`. Before executing static analysis operations, the worker entry point configures the runtime environment by establishing the global client asset suffix for Turbopack compiled code using `process.env.__NEXT_PRERENDER_CLIENT_ASSET_SUFFIX`.

```typescript
// Set the global asset suffix for Turbopack compiled code to use during prerendering
;(globalThis as any).NEXT_CLIENT_ASSET_SUFFIX =
  process.env.__NEXT_PRERENDER_CLIENT_ASSET_SUFFIX

```
Sources: [packages/next/src/build/worker.ts:9-12](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/worker.ts#L9-L12)

> [!NOTE]
> Native SWC bindings and code-frame support are installed explicitly inside the worker entry module rather than inside utility modules. This prevents devtools code-frame renderers from leaking into production server file traces while ensuring that errors thrown during static analysis render structured code frames.

Sources: [packages/next/src/build/worker.ts:14-20](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/worker.ts#L14-L20)

### Worker-Dispatched Utility Exports

The worker thread acts as an execution boundary exposing specialized static verification and export handlers to the master build orchestrator.

| Exported Handler / Function | Source File | Purpose |
| :--- | :--- | :--- |
| `isPageStatic` | `packages/next/src/build/worker.ts` | Installs SWC bindings and code frame support asynchronously before delegating to `isPageStaticImpl` |
| `getDefinedNamedExports` | `packages/next/src/build/worker.ts` | Re-exports module analysis utilities for identifying named exports from code |
| `hasCustomGetInitialProps` | `packages/next/src/build/worker.ts` | Re-exports page component inspection helpers to detect custom data fetching methods |
| `exportPages` | `packages/next/src/build/worker.ts` | Dispatches export page worker tasks for [static generation](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/static-generation) |

Sources: [packages/next/src/build/worker.ts:13-27](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/worker.ts#L13-L27)

## Post Build Manifest Processing

### Adapter Output Finalization and Route Fields

The build pipeline finalizes production artifacts by constructing structured metadata objects for routing adapters, server runtimes, and deployment platforms. Each entry point generated during compilation maps to shared route fields that capture asset boundaries, runtime environments, and segment configurations.

```typescript
interface SharedRouteFields {
  /**
   * id is the unique identifier of the output
   */
  id: string
  /**
   * filePath is the location on disk of the built entrypoint asset
   */
  filePath: string
  /**
   * pathname is the URL pathname the asset should be served at
   */
  pathname: string

  /**
   * sourcePage is the original source in the app or pages folder
   */
  sourcePage: string

  /**
   * runtime is which runtime the entrypoint is built for
   */
  runtime: 'nodejs' | 'edge'

  /**
   * assets are all necessary traced assets that could be
   * loaded by the output to handle a request e.g. traced
   * node_modules or necessary manifests for Next.js.
   * The key is the relative path from the repo root
   */
  assets: Record<string, string>

  /**
   * Hashes of the contents of each `assets` entry (not including the output path!)
   */
  assetsHashes: Record<string, string>

  /**
   * wasmAssets are bundled wasm files. The key is the (opaque) name of asset
   */
  wasmAssets?: Record<string, string>

  /**
   * edgeRuntime contains canonical entry metadata for invoking
   * this output in an edge runtime.
   */
  edgeRuntime?: {
    /**
     * modulePath is the canonical module path that registers this
     * output in the edge runtime.
     */
    modulePath: string
    /**
     * entryKey is the canonical key used for the global edge entry registry.
     */
    entryKey: string
    /**
     * handlerExport is the export name to invoke on the edge entry.
     */
    handlerExport: string
  }

  /**
   * config related to the route
   */
  config: {
    /**
     * maxDuration is a segment config to signal the max
     * execution duration a route should be allowed before
     * it's timed out
     */
    maxDuration?: number
    /**
     * preferredRegion is a segment config to signal deployment
     * region preferences to the provider being used
     */
    preferredRegion?: string | string[]

    /**
     * env is the environment variables to expose, this is only
```
Sources: [packages/next/src/build/adapter/build-complete.ts:73-157](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/adapter/build-complete.ts#L73-L157)

App paths sharing an identical URL pathname are collapsed into a single adapter output using `orderAppPageKeysByEntry`, which selects the canonical entry page to anchor merged asset tracking.

```typescript
function orderAppPageKeysByEntry(appPageKeys: readonly string[]): string[] {
  const appPathsByPathname = new Map<string, string[]>()

  for (const page of appPageKeys) {
    const pathname = normalizeAppPath(page)
    const appPaths = appPathsByPathname.get(pathname)

    if (appPaths) {
      appPaths.push(page)
    } else {
      appPathsByPathname.set(pathname, [page])
    }
  }

  const orderedAppPageKeys: string[] = []
  for (const [pathname, appPaths] of appPathsByPathname) {
    const entryPage = selectAppPageEntry(pathname, appPaths)
    orderedAppPageKeys.push(entryPage)

    for (const appPath of appPaths) {
```
Sources: [packages/next/src/build/adapter/build-complete.ts:212-231](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/adapter/build-complete.ts#L212-L231)

Prerender groups classify their primary responses through specific classification dimensions, separating non-UI routes, page shells, and full prerender outputs.

| Property | Allowed Values / Types | Meaning |
| :--- | :--- | :--- |
| `routeType` | `'route' \| 'fallback' \| 'shell' \| 'page'` | Canonical response category (non-UI route, partial fallback, page shell, or complete page) |
| `response` | `'empty' \| 'initial' \| 'complete'` | Completeness of the response prior to request-time work |
| `compute` | `'blocking' \| 'resuming' \| 'static'` | Request-time compute required to serve the completed response |
| `htmlSize` | `number` (optional) | Byte size of the prerendered HTML shell |

Sources: [packages/next/src/build/adapter/build-complete.ts:163-208](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/adapter/build-complete.ts#L163-L208)

### NFT File Tracing and Asset Mapping

Node File Tracing (NFT) processes emitted build artifacts to discover runtime dependencies, native bindings, and required configuration files. The build pipeline maps NFT file entries into asset records and computes content hashes for individual tracked files to ensure deployment bundles include every necessary module without extraneous files.

```typescript
import { mapNftFileEntries, type NftJson } from '../nft'
```
Sources: [packages/next/src/build/adapter/build-complete.ts:65-65](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/adapter/build-complete.ts#L65-L65)

> [!NOTE]
> Asset hash records track file contents explicitly across all traced dependencies (`assetsHashes`) to detect modifications between build and deployment phases without re-hashing output bundle files themselves.

Sources: [packages/next/src/build/adapter/build-complete.ts:106-108](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/adapter/build-complete.ts#L106-L108)

### Build-Complete Hooks and Telemetry Dispatch

Upon finishing all compilation stages, route discovery, and manifest serialization, the orchestrator triggers build-complete hooks and records build statistics via telemetry events. Success and failure states emit distinct events (`eventBuildCompleted` and `eventBuildFailed`) along with performance timings, feature usage analytics, and diagnostic metadata updates.

```typescript
eventBuildCompleted,
eventBuildFailed,
```
Sources: [packages/next/src/build/index.ts:120-121](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/index.ts#L120-L121)

## Related

- [Route Discovery](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/route-discovery)
- [Static Generation](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/static-generation)
- [Turbopack Engine](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/turbopack-engine)
- [Webpack Configuration](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/webpack-configuration)


## Sitemap

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