Open-Source Wikis

/

Next.js

/

Systems

/

Build pipeline

vercel/next.js

Build pipeline

next build is orchestrated by packages/next/src/build/index.ts — at 4,401 lines, the second-largest file in the framework. It coordinates discovery, compilation, analysis, static generation, manifest writing, and trace collection.

Stages

graph TD
    Start[next build] --> Config[Load + validate config<br/>server/config.ts]
    Config --> Discovery[Discover routes<br/>route-discovery.ts]
    Discovery --> Validate[validate-app-paths.ts]
    Validate --> Compile{Bundler}
    Compile -- default --> Turbopack[turbopack-build/]
    Compile -- --webpack --> Webpack[webpack-build/]
    Compile -- NEXT_RSPACK=1 --> Rspack[rspack via webpack-build]
    Turbopack --> Analyze[Static analysis<br/>analysis/, swc/]
    Webpack --> Analyze
    Rspack --> Analyze
    Analyze --> Static[Static generation<br/>static-paths/]
    Static --> Manifests[Write manifests<br/>manifests/, generate-routes-manifest.ts]
    Manifests --> Traces[Collect file traces<br/>collect-build-traces.ts]
    Traces --> Adapter[Adapter post-processing<br/>adapter/build-complete.ts]
    Adapter --> Done[Done]

Each stage is a function call from index.ts into a module under packages/next/src/build/. The stages run sequentially — the build is single-process by design (the bundler itself runs workers).

Discovery

packages/next/src/build/route-discovery.ts (15 KB) walks app/ and pages/ and produces:

  • A list of pages, layouts, error boundaries, loading boundaries, route handlers.
  • The page extensions (.ts, .tsx, .js, .mdx per next.config.js).
  • Conflict detection across the two routers.

validate-app-paths.ts (10 KB) catches structural errors: a route handler colocated with a page, a layout without children, missing default exports.

Compilation

Three bundler paths share most of their config but plug in different builders:

Path Driver
packages/next/src/build/turbopack-build/ crates/next-build via napi
packages/next/src/build/webpack-build/ webpack 5 (packages/next/src/compiled/webpack/)
packages/next/src/build/webpack-build/ + rspack rspack with packages/next-rspack/

The webpack config generator at packages/next/src/build/webpack-config.ts (2,936 lines) is shared between webpack and rspack. It produces three configurations per build:

  1. Server — Node-runtime server bundle
  2. Edge — Edge-runtime server bundle
  3. Client — Browser bundle

Each is generated for both production and (in dev) development. The webpack plugin set under packages/next/src/build/webpack/plugins/ provides Next.js-specific build behavior: route discovery into webpack entries, define-env injection, manifest generation, server reference manifests for server actions, and CSS chunking.

Build entries

packages/next/src/build/entries.ts (24 KB) decides which JavaScript entry points the bundler creates per route. Each App Router page produces three entries (server, edge, client) and each Pages Router page typically produces two (server, client). The entries reference templates under packages/next/src/build/templates/ like app-page.ts, app-route.ts, and pages.ts.

Templates

packages/next/src/build/templates/ is special: every file in it is compiled by the user's bundler at build time, not by the framework's own taskr build. That means relative require() calls in these files are resolved against the user's project, not the framework's own paths. New helpers must be exported from packages/next/src/server/app-render/entry-base.ts and accessed via entryBase.*.

Static analysis

After bundling, packages/next/src/build/analysis/ and packages/next/src/build/swc/ run additional passes:

  • Read each page's exported config (runtime, dynamic, revalidate, fetchCache, etc.).
  • Read segment configs from the loader tree (packages/next/src/build/segment-config/).
  • Decide each page's rendering mode: static, ISR, dynamic, or PPR.

The output is a per-route rendering plan that drives the next stage.

Static generation

packages/next/src/build/static-paths/ pre-renders pages whose paths are known at build time. For getStaticPaths (Pages Router) and generateStaticParams (App Router), the build runs the data-fetching function, then the renderer for each path.

A worker pool runs many static renders in parallel — see packages/next/src/server/dev/static-paths-worker.ts (also used at build time).

Manifests

After compilation and static generation, the build writes JSON manifests to .next/:

Manifest Purpose
routes-manifest.json All static + dynamic routes with their regexes
build-manifest.json Per-route asset list (Pages Router)
app-build-manifest.json Per-route asset list (App Router)
prerender-manifest.json Pre-rendered routes and their revalidation config
react-loadable-manifest.json Dynamically loaded modules
next-font-manifest.json Font preload data
server-reference-manifest.json Server actions inventory
client-reference-manifest.json Client component inventory
images-manifest.json Image optimization config
middleware-manifest.json Middleware bindings

The runtime reads these via packages/next/src/server/load-manifest.external.ts and packages/next/src/server/app-render/manifests-singleton.ts.

Build trace

Two unrelated traces are emitted:

  • Build trace at .next/trace — OpenTelemetry-format trace of the build itself, useful for performance analysis. Convert with scripts/trace-to-tree.mjs.
  • nft.json files — produced by packages/next/src/build/collect-build-traces.ts (22 KB). Per-route file lists used by hosting platforms to know which dependencies each route needs.

Adapter

After all of the above, hosting-platform-specific post-processing runs:

packages/next/src/build/adapter/build-complete.ts (2,215 lines) is the API surface platforms target. It receives the route inventory, manifests, and traces, and produces a platform deployment shape (function bundles, edge bundles, image config, headers, redirects, rewrites).

Vercel implements this externally; other hosting platforms can target the same surface.

define-env

packages/next/src/build/define-env.ts (16 KB) builds the process.env constants injected into user bundles via webpack's DefinePlugin. Critical rules:

  • For edge builds, force feature flags that gate Node-only imports to false so dead-code branches get eliminated. Otherwise edge bundles would fail to resolve node:stream and friends.
  • New flags in user-bundled code go here.
  • Flags consumed by pre-compiled runtime internals are independent of define-env.ts — they need separate plumbing through next-server.ts or export/worker.ts.

Compiler aliases

packages/next/src/build/create-compiler-aliases.ts (27 KB) builds the webpack/rspack/Turbopack aliases that point user code at the right vendored copy of React, the right react-server-dom-* package per layer, and the right module.compiled.js per runtime.

Polyfills

packages/next/src/build/polyfills/ injects Web Fetch, AbortController, structuredClone, and other modern-browser features for older targets. The packages/next-polyfill-module/ and packages/next-polyfill-nomodule/ packages are the actual bundles.

Integration points

  • The build is invoked by packages/next/src/cli/next-build.ts.
  • Manifest output is consumed by the server runtime at request time.
  • Static output is served by the caching layer.
  • Turbopack-driven builds delegate to the Rust crates (see crates).

Entry points for modification

  • To add a new build stage: edit packages/next/src/build/index.ts and add the corresponding module.
  • To add a new manifest: write the producer under packages/next/src/build/manifests/ and add a reader under packages/next/src/server/.
  • To change webpack config: packages/next/src/build/webpack-config.ts.
  • To add a new flag injected at build time: see feature-flag plumbing.

Key source files

File Purpose
packages/next/src/build/index.ts Build orchestrator
packages/next/src/build/route-discovery.ts Walk app/ and pages/ for routes
packages/next/src/build/validate-app-paths.ts Validate routing structure
packages/next/src/build/entries.ts Build webpack entries per route
packages/next/src/build/webpack-config.ts webpack config generator
packages/next/src/build/define-env.ts Build-time env injection
packages/next/src/build/create-compiler-aliases.ts Module aliases per layer/runtime
packages/next/src/build/handle-externals.ts Externalize Node modules from server bundle
packages/next/src/build/static-paths/ Static generation
packages/next/src/build/manifests/ Manifest writers
packages/next/src/build/generate-routes-manifest.ts routes-manifest.json writer
packages/next/src/build/collect-build-traces.ts nft.json producer
packages/next/src/build/adapter/build-complete.ts Platform adapter API
packages/next/src/build/templates/app-page.ts App page entry template (compiled by user bundler)
packages/next/src/build/templates/app-route.ts App route handler template

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Build pipeline – Next.js wiki | Factory