---
title: "Configuration Loading"
description: "Configuration loading in Next.js is responsible for discovering, transpiling, validating, and normalizing project configuration files (next.config.js, next.config.mjs, next.config.ts, and next.conf..."
last_updated: "2026-09-23T10:52:03.144385+00:00"
canonical_url: "https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-and-config/configuration-loading"
---

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

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

- [packages/next/src/server/config.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts)
- [packages/next/src/server/config-schema.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-schema.ts)
- [packages/next/src/server/config-shared.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-shared.ts)
- [packages/next/src/lib/load-custom-routes.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts)
- [packages/next/src/lib/find-config.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/find-config.ts)
- [packages/next/src/next-devtools/server/devtools-config-middleware.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/server/devtools-config-middleware.ts)
- [packages/next/src/server/lib/start-server.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/lib/start-server.ts)
- [packages/next/src/server/load-components.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/load-components.ts)
- [packages/next-env/index.ts](https://github.com/blade47/next-env/index.ts)
- [packages/next/src/server/next.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/next.ts)
- [packages/next/src/server/load-manifest.external.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/load-manifest.external.ts)
- [packages/next/src/lib/turbopack-warning.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts)
- [packages/next/src/next-devtools/shared/devtools-config-schema.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/shared/devtools-config-schema.ts)
- [packages/next/constants.js](https://github.com/blade47/next.js/blob/main/packages/next/constants.js)
- [packages/next/src/shared/lib/constants.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/shared/lib/constants.ts)
- [packages/next/src/server/config-utils.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-utils.ts)
- [packages/next/src/export/index.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/export/index.ts)
- [packages/next/src/server/require-hook.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/require-hook.ts)
- [packages/next/src/server/route-matcher-providers/helpers/manifest-loaders/node-manifest-loader.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/route-matcher-providers/helpers/manifest-loaders/node-manifest-loader.ts)
</details>

## Overview

Configuration loading in Next.js is responsible for discovering, transpiling, validating, and normalizing project configuration files (`next.config.js`, `next.config.mjs`, `next.config.ts`, and `next.config.mts`) across different runtime phases. It bridges user-defined settings with internal framework defaults, enforces strict Zod schema validation, and processes advanced features such as custom HTTP routes, experimental flags, and bundler compatibility checks before initializing server processes.

Sources: [packages/next/src/server/config.ts:1-60](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L1-L60), [packages/next/src/server/config-schema.ts:459-460](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-schema.ts#L459-L460), [packages/next/src/shared/lib/constants.ts:109-116](https://github.com/blade47/next.js/blob/main/packages/next/src/shared/lib/constants.ts#L109-L116)

## Config File Discovery and Resolution

Configuration discovery and loading operates by searching upward from a target directory for recognized configuration files using `findUp` and executing appropriate module loaders based on file extension and test environment constraints. The process resolves files defined by `CONFIG_FILES` or custom key lookups, supporting TypeScript transpilation, dynamic ESM imports, and CommonJS requires.

Sources: [packages/next/src/server/config.ts:4-9](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L4-L9), [packages/next/src/shared/lib/constants.ts:109-116](https://github.com/blade47/next.js/blob/main/packages/next/src/shared/lib/constants.ts#L109-L116)

The configuration loading execution path follows a strict sequence from directory traversal to module evaluation and normalization:
1. `findUp(CONFIG_FILES, { cwd: dir })` scans parent directories for configuration filenames starting from the provided working directory `dir`.
2. `basename(path)` extracts the specific `configFileName` when a path match is found.
3. Module evaluation branches depending on testing modes and file types:
   - If `process.env.__NEXT_TEST_MODE === 'jest'`, `require(path)` executes because dynamic `import()` is unsupported inside Jest VM contexts.
   - If `configFileName === 'next.config.ts'`, `transpileConfig({ nextConfigPath: path, dir })` compiles the TypeScript configuration file.
   - Otherwise, `import(pathToFileURL(path).href)` dynamically imports the module using URL-escaped file paths.
4. `normalizeConfig(phase, interopDefault(userConfigModule))` processes the exported user configuration, executing exported config functions if present.

Sources: [packages/next/src/server/config.ts:1861-1920](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L1861-L1920)

> [!NOTE]
> During Jest test execution (`process.env.__NEXT_TEST_MODE === 'jest'`), dynamic `import()` calls are bypassed in favor of synchronous `require(path)` to prevent Node.js VM context incompatibilities.

Sources: [packages/next/src/server/config.ts:1875-1879](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L1875-L1879)

In addition to primary Next.js server configuration discovery, the utility helper `findConfig` queries `package.json` configurations or falls back to known configuration file patterns via `findConfigPath`.

Sources: [packages/next/src/lib/find-config.ts:10-38](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/find-config.ts#L10-L38)

| Filename Pattern | Loader Type | Parsing Method | Sources |
|------------------|-------------|----------------|---------|
| `package.json` | JSON property lookup | `JSON.parse` with `packageJson[key]` extraction | [packages/next/src/lib/find-config.ts:40-60](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/find-config.ts#L40-L60) |
| `*.config.js` | Conditional (ESM / CJS) | `import()` if `package.json` specifies `type: "module"`, otherwise `require()` | [packages/next/src/lib/find-config.ts:81-86](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/find-config.ts#L81-L86) |
| `*.config.mjs` | ES Module | `import()` with `pathToFileURL` mapping on Windows | [packages/next/src/lib/find-config.ts:87-88](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/find-config.ts#L87-L88) |
| `*.config.cjs` | CommonJS | `require()` | [packages/next/src/lib/find-config.ts:89-90](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/find-config.ts#L89-L90) |
| JSON5 formats (`.*rc.json`, `*.config.json`, etc.) | JSON5 | `JSON5.parse` supporting inline comments | [packages/next/src/lib/find-config.ts:93-96](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/find-config.ts#L93-L96) |

Sources: [packages/next/src/lib/find-config.ts:40-97](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/find-config.ts#L40-L97)

> [!WARNING]
> Windows absolute paths passed to dynamic ESM imports require explicit `file://` protocol prefixing via `pathToFileURL()` unless executing within Jest worker environments.

Sources: [packages/next/src/server/config.ts:1871-1874](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L1871-L1874), [packages/next/src/lib/find-config.ts:68-78](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/find-config.ts#L68-L78)

## Schema Validation and Error Formatting

Next.js validates finalized configuration objects against comprehensive Zod schemas defined in `config-schema.ts`. When validation errors occur, diagnostic messages are normalized via `normalizeNextConfigZodErrors` to separate warning diagnostics from fatal build errors.

Sources: [packages/next/src/server/config.ts:60-110](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L60-L110), [packages/next/src/server/config-schema.ts:1-6](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-schema.ts#L1-L6)

The master validation schema `configSchema` is constructed using `z.lazy()` around a strict object (`z.strictObject`) to disallow unexpected top-level properties. Specialized sub-schemas validate routing configurations, custom image loaders, and experimental features.

Sources: [packages/next/src/server/config-schema.ts:459-460](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-schema.ts#L459-L460)

| Schema Identifier | Zod Definition Type | Purpose & Validation Rules | Sources |
|-------------------|---------------------|----------------------------|---------|
| `zRouteHas` | Union (`z.union`) | Validates custom route conditions matching `header`, `query`, `cookie` (with key and optional value) or `host` (value only). | [packages/next/src/server/config-schema.ts:49-60](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-schema.ts#L49-L60) |
| `zRewrite` | Strict Object (`z.strictObject`) | Validates rewrite rules containing `source`, `destination`, optional `basePath`, `locale`, `has`, `missing`, and `internal`. | [packages/next/src/server/config-schema.ts:62-70](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-schema.ts#L62-L70) |
| `zRedirect` | Object intersection (`z.and`) | Validates redirects, ensuring either `permanent` boolean or `statusCode` number is set exclusively without conflicts. | [packages/next/src/server/config-schema.ts:72-93](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-schema.ts#L72-L93) |
| `zHeader` | Strict Object (`z.strictObject`) | Validates custom response headers with array of `key`/`value` header objects and optional routing constraints. | [packages/next/src/server/config-schema.ts:95-104](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-schema.ts#L95-L104) |
| `zTurbopackLoaderBuiltinCondition` | Enum union (`z.union`) | Restricts Turbopack loader builtin conditions to `browser`, `foreign`, `development`, `production`, `node`, or `edge-light`. | [packages/next/src/server/config-schema.ts:115-123](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-schema.ts#L115-L123) |

Sources: [packages/next/src/server/config-schema.ts:49-123](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-schema.ts#L49-L123)

> [!CAUTION]
> Master validation enforces a strict object schema via `z.strictObject()`. Any unrecognized top-level properties supplied in `next.config.js` will trigger validation failure issues.

Sources: [packages/next/src/server/config-schema.ts:459-460](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-schema.ts#L459-L460)

When configuration validation runs, Zod issues are caught and processed by `normalizeNextConfigZodErrors` to determine whether diagnostics should halt the build or merely log warnings.

Sources: [packages/next/src/server/config.ts:60-110](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L60-L110)

The diagnostic normalization call-chain executes as follows:
`validateConfigSchema()` → `normalizeZodErrors(error)` → loops through validation issues to inspect `issue.path` and `issue.code` → applies targeted deprecation or migration advice → pushes items into `fatalErrors` or `warnings` arrays based on `shouldExit`.

Sources: [packages/next/src/server/config.ts:1958-1970](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L1958-L1970)

| Error Condition / Unrecognized Key | Target Property Path | Action Taken & Migration Notice | Sources |
|-------------------------------------|----------------------|---------------------------------|---------|
| Image config error | `issue.path[0] === 'images'` | Sets `shouldExit = true`, treating the image configuration issue as a fatal error that terminates the build. | [packages/next/src/server/config.ts:71-74](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L71-L74) |
| `turbopackPersistentCachingForBuild` | `issue.path[0] === 'experimental'` | Sets `shouldExit = true` and appends migration message directing users to `experimental.turbopackFileSystemCacheForBuild`. | [packages/next/src/server/config.ts:75-85](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L75-L85) |
| `turbopackPersistentCaching` | `issue.path[0] === 'experimental'` | Sets `shouldExit = true` and appends migration message directing users to `experimental.turbopackFileSystemCacheForDev`. | [packages/next/src/server/config.ts:86-92](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L86-L92) |
| `dynamicIO` | `issue.path[0] === 'experimental'` | Sets `shouldExit = true` and appends migration message replacing `dynamicIO` with `cacheComponents`. | [packages/next/src/server/config.ts:93-100](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L93-L100) |

Sources: [packages/next/src/server/config.ts:71-107](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L71-L107)

> [!NOTE]
> Specific experimental property errors like `turbopackPersistentCaching` and `dynamicIO` dynamically rewrite their error messages to instruct developers on newer replacement APIs before forcing a fatal exit.

Sources: [packages/next/src/server/config.ts:75-100](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L75-L100)

## Default Values and Config Normalization

Once the user configuration file has been discovered and successfully parsed, Next.js performs baseline normalization and combines user-supplied properties with built-in default settings. This phase ensures that every configuration object consumed by downstream compilation and runtime systems contains predictable structure and fallback values even when specific properties are omitted by the developer.

Sources: [packages/next/src/server/config-shared.ts:2092-2098](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-shared.ts#L2092-L2098), [packages/next/src/server/config.ts:15-20](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L15-L20)

The normalization utility evaluates whether the exported configuration is a static object or a dynamic function exported by the user.

Sources: [packages/next/src/server/config.ts:1915-1920](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L1915-L1920)

The configuration normalization execution walk-through proceeds as follows:
`loadConfig()` (or module load) → `normalizeConfig(phase, interopDefault(userConfigModule))` → checks if `typeof config === 'function'` → if functional, executes `config(phase, { defaultConfig })` passing the current phase and default settings object → awaits any returned asynchronous promise → returns the finalized configuration object.

Sources: [packages/next/src/server/config-shared.ts:2092-2098](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-shared.ts#L2092-L2098)

> [!NOTE]
> If the user export is a function, it receives the execution `phase` string and an argument bag containing `defaultConfig`. This allows conditional configuration based on whether Next.js is running in development, production build, or export mode.

Sources: [packages/next/src/server/config-shared.ts:2093-2095](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-shared.ts#L2093-L2095)

The `defaultConfig` object provides fallback options for experimental properties, server options, and build structures. Specific experimental features incorporate contextual environment helpers such as `turbopackFileSystemCacheForBuildDefault()` to decide appropriate defaults based on CI environments or stable build flags.

Sources: [packages/next/src/server/config-shared.ts:2066-2090](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-shared.ts#L2066-L2090)

| Default Property | Baseline Value / Behavior | Purpose / Context | Sources |
|------------------|---------------------------|-------------------|---------|
| `globalNotFound` | `false` | Controls global 404 behavior across app routes. | [packages/next/src/server/config-shared.ts:2068-2068](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-shared.ts#L2068-L2068) |
| `browserDebugInfoInTerminal` | `'warn'` | Configures logging level for browser debug information in the terminal. | [packages/next/src/server/config-shared.ts:2069-2069](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-shared.ts#L2069-L2069) |
| `lockDistDir` | `true` | Locks the distribution directory during build/runtime operations. | [packages/next/src/server/config-shared.ts:2070-2070](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-shared.ts#L2070-L2070) |
| `proxyClientMaxBodySize` | `10_485_760` (10MB) | Sets maximum body size allowed for proxy client requests. | [packages/next/src/server/config-shared.ts:2071-2071](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-shared.ts#L2071-L2071) |
| `mcpServer` | `true` | Enables Model Context Protocol server capabilities. | [packages/next/src/server/config-shared.ts:2073-2073](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-shared.ts#L2073-L2073) |
| `turbopackFileSystemCacheForDev` | `true` | Enables Turbopack file system caching during development. | [packages/next/src/server/config-shared.ts:2074-2074](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-shared.ts#L2074-L2074) |
| `turbopackPluginRuntimeStrategy` | `'childProcesses'` | Sets runtime execution strategy for Turbopack plugins. | [packages/next/src/server/config-shared.ts:2077-2077](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-shared.ts#L2077-L2077) |

Sources: [packages/next/src/server/config-shared.ts:2066-2081](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-shared.ts#L2066-L2081)

> [!WARNING]
> `turbopackFileSystemCacheForBuild` evaluates dynamically via `turbopackFileSystemCacheForBuildDefault()`. It returns `false` on stable builds unless running inside Vercel CI builder environments where remote caching is guaranteed.

Sources: [packages/next/src/server/config-shared.ts:2083-2090](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-shared.ts#L2083-L2090)

## Custom Routes and Headers Processing

Custom routes and HTTP headers processing is orchestrated via `loadCustomRoutes()`, which concurrently evaluates user-defined asynchronous configuration functions for headers, rewrites, and redirects. Each category undergoes schema validation, prefix and locale transformation passes via `processRoutes()`, and aggregation checks to safeguard server performance.

Sources: [packages/next/src/lib/load-custom-routes.ts:703-710](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L703-L710), [packages/next/src/server/config.ts:16-20](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L16-L20)

When loading user-defined routing rules, execution proceeds through a strict validation and transformation pipeline:
`loadCustomRoutes(config)` → executes `Promise.all([loadHeaders(config), loadRewrites(config), loadRedirects(config)])` concurrently → within each loader (e.g., `loadRedirects()`), checks if `typeof config.redirects === 'function'`, awaits the returned array, invokes `checkCustomRoutes(redirects, 'redirect')`, saves raw unedited redirects to `config._originalRedirects`, applies `processRoutes(redirects, config, 'redirect')` to inject base paths and i18n locale prefixes, re-runs `checkCustomRoutes()`, and returns the finalized rules.

Sources: [packages/next/src/lib/load-custom-routes.ts:585-601](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L585-L601), [packages/next/src/lib/load-custom-routes.ts:689-710](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L689-L710)

> [!WARNING]
> If the combined total of custom headers, redirects, and rewrites exceeds 1000 items, `loadCustomRoutes()` emits a performance warning to the console.

Sources: [packages/next/src/lib/load-custom-routes.ts:714-730](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L714-L730)

Rewrites support structural categorization into three distinct execution phases, parsed from an object return value containing `beforeFiles`, `afterFiles`, and `fallback` arrays. Asset prefix rewrites are automatically prepended to `beforeFiles` unless they collide with the configured base path.

Sources: [packages/next/src/lib/load-custom-routes.ts:609-630](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L609-L630), [packages/next/src/lib/load-custom-routes.ts:644-657](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L644-L657)

| Route Type / Property | Sub-property / Phase | Purpose / Processing Behavior | Sources |
|-----------------------|----------------------|-------------------------------|---------|
| `rewrites` | `beforeFiles` | Rewrites executed before checking pages, public files, and build assets. | [packages/next/src/lib/load-custom-routes.ts:496](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L496), [packages/next/src/lib/load-custom-routes.ts:652](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L652) |
| `rewrites` | `afterFiles` | Rewrites executed after checking pages, public files, and dynamic routes. | [packages/next/src/lib/load-custom-routes.ts:495](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L495), [packages/next/src/lib/load-custom-routes.ts:653](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L653) |
| `rewrites` | `fallback` | Rewrites executed only after all pages and dynamic fallback routes fail to match. | [packages/next/src/lib/load-custom-routes.ts:494](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L494), [packages/next/src/lib/load-custom-routes.ts:654](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L654) |
| `headers` | `onMatchHeaders` | Internal routing headers populated when deployment ID or skew cookies are active. | [packages/next/src/lib/load-custom-routes.ts:492](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L492), [packages/next/src/lib/load-custom-routes.ts:712](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L712) |

Sources: [packages/next/src/lib/load-custom-routes.ts:490-499](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L490-L499), [packages/next/src/lib/load-custom-routes.ts:652-654](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L652-L654)

> [!TIP]
> When `config.deploymentId` and `config.experimental.useSkewCookie` are both enabled, `loadCustomRoutes()` automatically prepends a global cookie-setting header rule (`__vdpl=...`) and matches incoming requests containing the RSC header to coordinate deployment state.

Sources: [packages/next/src/lib/load-custom-routes.ts:753-777](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/load-custom-routes.ts#L753-L777)

## Experimental Flags and Deprecation Checks

Once the base configuration object is loaded and parsed, Next.js inspects its properties for deprecated options, records configured canary and experimental features, and validates Turbopack configuration compatibility. This lifecycle stage ensures that outdated configuration properties emit actionable migration warnings and that builds running under Turbopack do not inadvertently rely on unsupported Webpack-centric options.

Sources: [packages/next/src/server/config.ts:112-157](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L112-L157)

The deprecation inspection workflow is governed by `checkDeprecations()` and `warnOptionHasBeenDeprecated()`. When config loading completes, `checkDeprecations()` examines the raw user configuration for legacy fields.

Sources: [packages/next/src/server/config.ts:139-156](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L139-L156)

Adding an entry: `checkDeprecations()` → calls `warnOptionHasBeenDeprecated()` for each legacy key → splits `nestedPropertyKey` by dots to walk the configuration tree → if `found` is true, invokes `Log.warnOnce(reason)` and returns `hasWarned = true`.

Sources: [packages/next/src/server/config.ts:112-137](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L112-L137)

| Legacy Option Key | Replacement Option Key | Warning Reason / Message Format | Sources |
|-------------------|------------------------|---------------------------------|---------|
| `experimental.middlewarePrefetch` | `experimental.proxyPrefetch` | `\`experimental.middlewarePrefetch\` is deprecated. Please use \`experimental.proxyPrefetch\` instead in {configFileName}.` | [packages/next/src/server/config.ts:145-150](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L145-L150) |
| `experimental.middlewareClientMaxBodySize` | `experimental.proxyClientMaxBodySize` | `\`experimental.middlewareClientMaxBodySize\` is deprecated. Please use \`experimental.proxyClientMaxBodySize\` instead in {configFileName}.` | [packages/next/src/server/config.ts:151-156](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L151-L156) |

Sources: [packages/next/src/server/config.ts:145-156](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L145-L156)

> [!WARNING]
> If a Zod schema validation error encounters unrecognized keys under `experimental`, specific fields like `turbopackPersistentCachingForBuild` or `turbopackPersistentCaching` force an immediate fatal exit by pushing the error into `fatalErrors` and pointing developers to `turbopackFileSystemCacheForBuild` or `turbopackFileSystemCacheForDev`.

Sources: [packages/next/src/server/config.ts:75-92](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config.ts#L75-L92)

When builds execute with Turbopack, `validateTurboNextConfig()` ensures that unsupported options are caught and reported.

Sources: [packages/next/src/lib/turbopack-warning.ts:41-69](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L41-L69)

Calling `validateTurboNextConfig({ dir, configPhase })` executes the following sequence:
1. `loadConfig(configPhase, dir, { rawConfig: true })` loads the un-normalized configuration object.
2. `flattenKeys(rawNextConfig)` recursively extracts all nested property keys from the object while skipping undefined values.
3. For each flattened key, it checks whether the key starts with any entry in `unsupportedTurbopackNextConfigOptions` and ensures its value differs from `defaultConfig`.
4. If `process.env.TURBOPACK === 'auto'`, `hasWebpackConfig` is true, and `hasTurboConfig` is false, it logs a critical error and terminates the process with `process.exit(1)`.

Sources: [packages/next/src/lib/turbopack-warning.ts:41-166](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L41-L166)

| Unsupported Option Path | Classification | Sources |
|-------------------------|----------------|---------|
| `experimental.fetchCacheKeyPrefix` | Experimental feature left to be implemented for Turbopack | [packages/next/src/lib/turbopack-warning.ts:14-14](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L14-L14) |
| `experimental.clientRouterFilterAllowedRate` | Experimental feature left to be implemented | [packages/next/src/lib/turbopack-warning.ts:19-19](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L19-L19) |
| `experimental.allowedRevalidateHeaderKeys` | Experimental feature unsupported by Turbopack | [packages/next/src/lib/turbopack-warning.ts:23-23](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L23-L23) |
| `experimental.extensionAlias` | Experimental feature unsupported by Turbopack | [packages/next/src/lib/turbopack-warning.ts:24-24](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L24-L24) |
| `experimental.fallbackNodePolyfills` | Experimental feature unsupported by Turbopack | [packages/next/src/lib/turbopack-warning.ts:25-25](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L25-L25) |
| `experimental.swcTraceProfiling` | Experimental feature unsupported by Turbopack | [packages/next/src/lib/turbopack-warning.ts:27-27](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L27-L27) |
| `experimental.craCompat` | Compatibility flag that might not be needed for Turbopack | [packages/next/src/lib/turbopack-warning.ts:30-30](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L30-L30) |
| `experimental.disablePostcssPresetEnv` | Compatibility flag that might not be needed for Turbopack | [packages/next/src/lib/turbopack-warning.ts:31-31](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L31-L31) |
| `experimental.esmExternals` | Compatibility flag that might not be needed for Turbopack | [packages/next/src/lib/turbopack-warning.ts:32-32](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L32-L32) |
| `experimental.forceSwcTransforms` | Force swc-loader option unsupported by Turbopack | [packages/next/src/lib/turbopack-warning.ts:33-34](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L33-L34) |
| `experimental.fullySpecified` | Compatibility flag unsupported by Turbopack | [packages/next/src/lib/turbopack-warning.ts:35-35](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L35-L35) |
| `experimental.urlImports` | Compatibility flag unsupported by Turbopack | [packages/next/src/lib/turbopack-warning.ts:36-36](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L36-L36) |
| `experimental.slowModuleDetection` | Compatibility flag unsupported by Turbopack | [packages/next/src/lib/turbopack-warning.ts:37-37](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L37-L37) |

Sources: [packages/next/src/lib/turbopack-warning.ts:14-37](https://github.com/blade47/next.js/blob/main/packages/next/src/lib/turbopack-warning.ts#L14-L37)

## Require Hooks and Process Initialization

Next.js configures Node.js module resolution during process initialization by installing custom require hooks that route userland webpack requests to the internal bundled webpack instance. The initialization utility `loadWebpackHook()` ensures that hooks are installed exactly once per process via an `installed` boolean flag.

Sources: [packages/next/src/server/config-utils.ts:1-7](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-utils.ts#L1-L7)

When invoked, `loadWebpackHook()` delegates to `addHookAliases()` from `packages/next/src/server/require-hook.ts`, populating `hookPropertyMap` with precise mappings for webpack packages, source modules, and plugins.

Sources: [packages/next/src/server/config-utils.ts:8-144](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-utils.ts#L8-L144), [packages/next/src/server/require-hook.ts:40-44](https://github.com/blade47/next.js/blob/main/packages/next/src/server/require-hook.ts#L40-L44)

| Request Alias | Replacement Target | Sources |
|--------------------------------------------------|-------------------------------------------------------------------|---------|
| `webpack` | `next/dist/compiled/webpack/webpack-lib` | [packages/next/src/server/config-utils.ts:15-15](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-utils.ts#L15-L15) |
| `webpack/package` / `webpack/package.json` | `next/dist/compiled/webpack/package` | [packages/next/src/server/config-utils.ts:16-17](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-utils.ts#L16-L17) |
| `webpack/lib/webpack` / `webpack/lib/webpack.js` | `next/dist/compiled/webpack/webpack-lib` | [packages/next/src/server/config-utils.ts:18-19](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-utils.ts#L18-L19) |
| `webpack/lib/node/NodeEnvironmentPlugin` | `next/dist/compiled/webpack/NodeEnvironmentPlugin` | [packages/next/src/server/config-utils.ts:21-23](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-utils.ts#L21-L23) |
| `webpack-sources` | `next/dist/compiled/webpack/sources` | [packages/next/src/server/config-utils.ts:130-130](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-utils.ts#L130-L130) |
| `@babel/runtime` | `next/dist/compiled/@babel/runtime/package.json` | [packages/next/src/server/config-utils.ts:134-134](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-utils.ts#L134-L134) |

Sources: [packages/next/src/server/config-utils.ts:15-134](https://github.com/blade47/next.js/blob/main/packages/next/src/server/config-utils.ts#L15-L134)

The require hook overrides `mod._resolveFilename` to intercept module resolution requests. If a requested identifier matches a key in `hookPropertyMap`, it is swapped with the resolved internal path before executing `originalResolveFilename.call()`.

Sources: [packages/next/src/server/require-hook.ts:49-68](https://github.com/blade47/next.js/blob/main/packages/next/src/server/require-hook.ts#L49-L68)

> [!NOTE]
> `mod.prototype.require` is also patched to intercept shared runtime requests ending with `.shared-runtime`, routing them directly to the vendored contexts directory for the Pages router.

Sources: [packages/next/src/server/require-hook.ts:74-86](https://github.com/blade47/next.js/blob/main/packages/next/src/server/require-hook.ts#L74-L86)

## Related

- [CLI Commands](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-and-config/cli-commands)


## Sitemap

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