---
title: "Monorepo Workspace"
description: "The Next.js repository is structured as a multi-package and multi-engine monorepo governed by declarative workspace configurations. It combines Node.js package management with Rust workspace orches..."
last_updated: "2026-10-12T06:38:56.847842+00:00"
canonical_url: "https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/orientation/monorepo-workspace"
---

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

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

- [pnpm-workspace.yaml](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/pnpm-workspace.yaml)
- [packages/next-codemod/lib/agents-md.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next-codemod/lib/agents-md.ts)
- [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)
- [package.json](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/package.json)
- [turbo.json](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/turbo.json)
- [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/create-next-app/templates/index.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/create-next-app/templates/index.ts)
- [conductor.json](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/conductor.json)
- [packages/next/src/build/swc/index.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/swc/index.ts)
- [packages/next/src/build/turborepo-access-trace/index.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/turborepo-access-trace/index.ts)
- [Cargo.toml](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/Cargo.toml)
- [run-evals.js](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/run-evals.js)
- [packages/next/src/build/webpack/loaders/next-app-loader/index.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack/loaders/next-app-loader/index.ts)
- [packages/next-codemod/turbo.json](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next-codemod/turbo.json)
- [socket.yaml](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/socket.yaml)
- [packages/next-codemod/bin/upgrade.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next-codemod/bin/upgrade.ts)
- [packages/next/turbo.json](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/turbo.json)
- [packages/next-codemod/lib/handle-package.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next-codemod/lib/handle-package.ts)
- [packages/next/src/lib/turbopack-cache-seed.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/lib/turbopack-cache-seed.ts)
- [packages/next/src/lib/find-root.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/lib/find-root.ts)
- [packages/next/package.json](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/package.json)
- [run-tests.js](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/run-tests.js)
- [packages/next/src/server/lib/chrome-devtools-workspace.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/server/lib/chrome-devtools-workspace.ts)
- [packages/next/src/build/utils.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/utils.ts)
</details>

## Overview

The Next.js repository is structured as a multi-package and multi-engine monorepo governed by declarative workspace configurations. It combines Node.js package management with Rust workspace orchestration to coordinate builds, internal packaging, and testing across disparate subdirectories.

Sources: [pnpm-workspace.yaml:1-7](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/pnpm-workspace.yaml#L1-L7), [Cargo.toml:1-18](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/Cargo.toml#L1-L18)

## PNPM Workspace Layout and Boundaries

### Workspace Directory Patterns and Glob Mappings

The monorepo workspace structure is governed declaratively by `pnpm-workspace.yaml`, which specifies pattern globs to map applications, packages, benchmarks, and compiler bindings into the unified dependency tree. The `packages` entry defines active workspace members across seven distinct directory paths.

| Workspace Pattern Glob | Target Component Category |
| :--- | :--- |
| `apps/*` | End-user applications and deployment fixtures |
| `packages/*` | Core shared libraries, developer tooling, and internal packages |
| `bench/*` | Performance benchmark suites |
| `crates/*/js` | JavaScript bindings for individual root-level Rust crates |
| `turbopack/crates/*/js` | JavaScript bindings for Turbopack-specific Rust crates |
| `turbopack/crates/turbopack-tests/tests/execution` | Turbopack execution test suites |

Sources: [pnpm-workspace.yaml:1-7](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/pnpm-workspace.yaml#L1-L7)

### Package Manager and Security Restrictions

The root `package.json` designates `pnpm@10.33.0` as the explicit package manager and sets a minimum Node.js engine requirement of `>=20.9.0`. Security policies and dependency constraints are enforced directly within the workspace configuration.

| Workspace Setting | Value | Behavior |
| :--- | :--- | :--- |
| `updateNotifier` | `false` | Disables automated version check notifications during CLI execution |
| `blockExoticSubdeps` | `true` | Prevents installation of non-standard or unexpected subdependency sources |
| `minimumReleaseAge` | `2880` (48 hours) | Enforces a minimum delay before newly published registry versions can be installed |

Sources: [pnpm-workspace.yaml:8-37](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/pnpm-workspace.yaml#L8-L37), [package.json:302-305](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/package.json#L302-L305)

> [!NOTE]
> Security settings including `blockExoticSubdeps` and `minimumReleaseAge` are synchronized with temporary fixture directories created by `scripts/install-native.mjs` and verified by `test/lib/pnpm-security-settings.js`.

Sources: [pnpm-workspace.yaml:32-35](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/pnpm-workspace.yaml#L32-L35)

### Excluded Dependencies and Overrides

Certain built dependencies and package versions are exempted from workspace constraints or explicitly overridden at the root level. The workspace allows native builds for `@ast-grep/cli` while ignoring build scripts for performance-critical or native packages.

- **Ignored Build Dependencies:** `@datadog/native-appsec`, `@datadog/native-metrics`, `@datadog/pprof`, `@swc/core`, `@tailwindcss/oxide`, `core-js`, `cpu-features`, `dd-trace`, `esbuild`, `msw`, `nx`, `playwright-chromium`, `protobufjs`, `sharp`, `ssh2`, `unrs-resolver`, `wasm-pack`
- **Minimum Release Age Exclusions:** `@mswjs/interceptors@0.42.6`, `@next/*`, `@turbo/*`, `@types/react@19.2.18`, `@types/react-dom@19.2.4`, `@vercel/*`, `@workflow/*`, `babel-plugin-react-compiler`, `httpxy@0.5.5`, `next`, `react`, `react-dom`, `react-is`, `react-server-dom-*`, `satori@0.33.5`, `scheduler`, `turbo`

Sources: [pnpm-workspace.yaml:11-55](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/pnpm-workspace.yaml#L11-L55)

> [!WARNING]
> Patched dependencies defined in the root manifest override external package behaviors for modules such as `webpack-sources@3.2.3`, `stacktrace-parser@0.1.10`, `@rspack/core@1.6.7`, and `@vercel/og@1.0.1`.

Sources: [package.json:333-346](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/package.json#L333-L346)

## Turborepo Task Pipeline Coordination

### Root Task Topologies and Global Environment

The root `turbo.json` configures task execution semantics, global environment tracking, and concurrency options for the monorepo. It establishes the Turborepo schema, enables the terminal user interface (`"ui": "tui"`), and defines global variables that invalidate caches when altered.

| Global Configuration Key | Value | Purpose |
| :--- | :--- | :--- |
| `globalEnv` | `["CI", "NEXT_CI_RUNNER"]` | Tracks CI execution state in cache keys |
| `globalPassThroughEnv` | `["RUSTC_WRAPPER", "SCCACHE_*"]` | Forwards Rust compilation cache settings |
| `ui` | `"tui"` | Enables the interactive Turborepo terminal interface |

Sources: [turbo.json:1-4](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/turbo.json#L1-L4), [turbo.json:34-34](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/turbo.json#L34-L34)

The root task definitions govern core commands across workspace packages, specifying dependencies, file inputs, and generated outputs.

| Task Name | `dependsOn` | `inputs` | `outputs` | `env` |
| :--- | :--- | :--- | :--- | :--- |
| `build` | `["^build"]` | — | `["dist/**"]` | — |
| `dev` | `["^dev"]` | — | `["dist/**"]` | — |
| `storybook` | — | — | — | — |
| `build-storybook` | `["^build-storybook"]` | — | `["storybook-static/**"]` | — |
| `test-storybook` | `["^test-storybook"]` | — | — | — |
| `pack-for-isolated-tests` | — | `["$TURBO_DEFAULT$", "dist/**"]` | `["packed.tgz"]` | — |
| `typescript` | — | — | — | — |
| `//#typescript` | — | — | — | — |
| `//#get-test-timings` | — | `["run-tests.js"]` | `["test-timings.json"]` | `["KV_REST_API_URL", "KV_REST_API_TOKEN"]` |

Sources: [turbo.json:5-33](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/turbo.json#L5-L33)

> [!NOTE]
> Tasks prefixed with `//#` execute exclusively at the root workspace level rather than propagating across individual package members.

Sources: [turbo.json:27-32](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/turbo.json#L27-L32)

### Package-Specific Task Overrides

Individual packages extend the root Turborepo configuration to tailor build outputs and topological constraints for specialized deliverables. The `packages/next/turbo.json` manifest customizes the primary `build` task by requiring [bundle analyzer](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/companion-packages/bundle-analyzer) UI compilation before executing package assembly.

```json
{
  "$schema": "https://turborepo.org/schema.json",
  "extends": ["//"],
  "tasks": {
    "build": {
      "dependsOn": ["@next/bundle-analyzer-ui#build", "^build"],
      "outputs": ["dist/**"]
    }
  }
```
Sources: [packages/next/turbo.json:1-9](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/turbo.json#L1-L9)

Similarly, `packages/next-codemod/turbo.json` extends the root pipeline (`"extends": ["//"]`) to specify granular file outputs for both production build and development tasks, excluding test fixtures and test suites from cache artifacts.

```json
{
  "$schema": "https://turbo.build/schema.json",
  "extends": ["//"],
  "tasks": {
    "build": {
      "outputs": [
        "**/*.js",
        "**/*.d.ts",
        "**/*.js.map",
        "!bin/__testfixtures__/**",
        "!transforms/__testfixtures__/**",
        "!transforms/__tests__/**"
      ]
    },
    "dev": {
      "outputs": [
        "**/*.js",
        "**/*.d.ts",
        "**/*.js.map",
        "!bin/__testfixtures__/**",
        "!transforms/__testfixtures__/**",
        "!transforms/__tests__/**"
      ]
    }
  }
```
Sources: [packages/next-codemod/turbo.json:1-25](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next-codemod/turbo.json#L1-L25)

> [!CAUTION]
> Failing to exclude test directories from package output globs can pollute the Turborepo cache with transient test artifacts, causing inconsistent build state invalidations across CI runs.

Sources: [packages/next-codemod/turbo.json:10-13](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next-codemod/turbo.json#L10-L13), [packages/next-codemod/turbo.json:20-23](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next-codemod/turbo.json#L20-L23)

## Internal Packaging and Task Automation

### Task Automation and Compilation Pipelines

The `packages/next/taskfile.js` script manages internal compilation routines, file watching, and output targets for the package using Taskr. The default export sequence clears the `dist` directory, invokes the primary release build, and establishes file watchers across source subdirectories like `src/bin`, `src/pages`, `src/server`, `src/client`, `src/lib`, and `src/cli`.

```javascript
export default async function (task) {
  const opts = { dev: true }
  await task.clear('dist')
  await task.start('build', opts)
  await task.watch('src/bin', 'bin', opts)
  await task.watch('src/pages', 'pages', opts)
  await task.watch('src/server', ['server', 'server_esm', 'server_wasm'], opts)
  await task.watch('src/api', 'api_esm', opts)
  await task.watch(
    'src/build',
    ['nextbuild', 'nextbuild_esm', 'nextbuildjest'],
    opts
  )
  await task.watch(
    'src/next-devtools',
    [
      'next_devtools_entrypoint',
      'next_devtools_server',
      'next_devtools_server_esm',
      'next_devtools_shared',
      'next_devtools_shared_esm',
      'next_devtools_userspace',
      'next_devtools_userspace_esm',
    ],
    opts
  )
  await task.watch('src/experimental/testing', 'experimental_testing', opts)
  await task.watch('src/experimental/testmode', 'experimental_testmode', opts)
  await task.watch('src/export', 'nextbuildstatic', opts)
  await task.watch('src/export', 'nextbuildstatic_esm', opts)
  await task.watch('src/client', 'client', opts)
  await task.watch('src/client', 'client_esm', opts)
  await task.watch('src/diagnostics', 'diagnostics', opts)
  await task.watch('src/lib', 'lib', opts)
  await task.watch('src/lib', 'lib_esm', opts)
  await task.watch('src/cli', 'cli', opts)
  await task.watch('src/telemetry', 'telemetry', opts)
  await task.watch('src/trace', 'trace', opts)
  await task.watch(
    'src/shared',
    ['shared_re_exported', 'shared_re_exported_esm', 'shared', 'shared_esm'],
    opts
  )
}
```
Sources: [packages/next/taskfile.js:2785-2828](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/taskfile.js#L2785-L2828)

Specialized functions handle transformations for shared utilities, Webpack runtime bundles, and WebAssembly assets. For instance, `shared` and `shared_esm` tasks compile files under `src/shared/` while ignoring tests and dynamic entry points, targeting `dist/shared` and `dist/esm/shared` respectively.

| Task Name | Source Pattern | Target Directory | Compiler / Tool | Options / Flags |
| :--- | :--- | :--- | :--- | :--- |
| `shared` | `src/shared/**/*.+(js|ts|tsx)` | `dist/shared` | SWC | `dev: opts.dev` |
| `shared_esm` | `src/shared/**/*.+(js|ts|tsx)` | `dist/esm/shared` | SWC | `dev: opts.dev, esm: true` |
| `server_wasm` | `src/server/**/*.+(wasm)` | `dist/server` | Direct copy | — |
| `experimental_testing` | `src/experimental/testing/**/!(*.test).+(js|ts|tsx)` | `dist/experimental/testing` | SWC | `dev: opts.dev` |
| `experimental_testmode` | `src/experimental/testmode/**/!(*.test).+(js|ts|tsx)` | `dist/experimental/testmode` | SWC | `dev: opts.dev` |

Sources: [packages/next/taskfile.js:2830-2904](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/taskfile.js#L2830-L2904)

> [!TIP]
> The `generate_types` task conditionally passes `--watch` and `--preserveWatchOutput` flags to TypeScript compiler processes when `opts.dev` is active, keeping declaration generation running continuously during development.

Sources: [packages/next/taskfile.js:2767-2783](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/taskfile.js#L2767-L2783)

### Package Metadata and Script Definitions

The `packages/next/package.json` file declares core workspace identity, package entry points, binary mappings, and script automation hooks. It assigns `dist/server/next.js` as the main entry point and exposes the CLI binary via the `bin` mapping.

Sources: [packages/next/package.json:1-10](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/package.json#L1-L10), [packages/next/package.json:83-96](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/package.json#L83-L96)

The manifest enumerates runtime dependencies, peer requirements, and development tooling. The `taskr` configuration block explicitly registers required taskfile extensions for Webpack, NCC, SWC, and file watching.

| Package Manifest Key | Value / Target | Description |
| :--- | :--- | :--- |
| `name` | `"next"` | Workspace package identifier |
| `version` | `"16.5.0-canary.8"` | Current semantic version release string |
| `main` | `"./dist/server/next.js"` | Primary CommonJS entry point |
| `types` | `"index.d.ts"` | Root TypeScript declaration file |
| `bin.next` | `"./dist/bin/next"` | Command-line executable mapping |
| `scripts.dev` | `"cross-env NEXT_SERVER_NO_MANGLE=1 taskr"` | Starts development task runner with unmangled server output |
| `scripts.build` | `"taskr release"` | Clears distribution and executes full release compilation |
| `scripts.types` | `tsc --project tsconfig.build.json ...` | Emits isolated type declarations into `dist` |
| `taskr.requires` | `["./taskfile-webpack.js", ...]` | Taskr plugin modules loaded at runtime |

Sources: [packages/next/package.json:1-10](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/package.json#L1-L10), [packages/next/package.json:83-104](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/package.json#L83-L104)

> [!CAUTION]
> The `files` array in `packages/next/package.json` explicitly whitelists published distribution folders, type definitions, and experimental entry points (`experimental/testing/server.js`, `experimental/testmode/playwright.js`); omitting a built artifact from this list prevents it from being included when packed to registry tarballs.

Sources: [packages/next/package.json:11-82](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/package.json#L11-L82)

## Turborepo Access Tracing and Caching

### Cache Seeding and Worktree Resolution

Integration between the Next.js build runtime and workspace caching mechanisms relies on programmatic access tracing and cache seeding across Git worktrees. The Next.js build infrastructure exports helper utilities from `packages/next/src/build/turborepo-access-trace/index.ts` to coordinate Turborepo access tracing (`turborepoTraceAccess`, `writeTurborepoAccessTraceResult`, and `TurborepoAccessTraceResult`), enabling build pipelines to record file system and dependency accesses required for correct remote and local task caching.

```typescript
export type { SerializableTurborepoAccessTraceResult } from './types'
export {
  turborepoTraceAccess,
  writeTurborepoAccessTraceResult,
} from './helpers'
export { TurborepoAccessTraceResult } from './result'
```
Sources: [packages/next/src/build/turborepo-access-trace/index.ts:1-6](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/turborepo-access-trace/index.ts#L1-L6)

To accelerate builds across isolated Git worktrees within a monorepo workspace, `seedTurbopackCacheIfNeeded` inspects the project directory and distribution path to seed local Turbopack caches from existing worktree sources.

```typescript
export function seedTurbopackCacheIfNeeded({
  projectDir,
  distDir,
}: {
  projectDir: string
  distDir: string
}): void {
  // This gets the version assuming that nothing is dirty.
  // If things are dirty, turbopack would write things
  // in a different location. There are other circumstances
  // as well. This only matters for people developing turbopack
  // see handle_db_versioning in turbotask backend for more details.
  const version = getTurbopackCacheVersion()
  if (!version) return

  const worktreeInfo = getGitWorktreeInfo(projectDir)
  if (!worktreeInfo) return

  const cacheDir = path.join(distDir, 'cache', 'turbopack')
  const targetVersionDir = path.join(cacheDir, version)
  if (dirHasEntries(targetVersionDir)) return

```
Sources: [packages/next/src/lib/turbopack-cache-seed.ts:11-32](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/lib/turbopack-cache-seed.ts#L11-L32)

When a project build executes, `findSeedSource` scans the main repository root and linked worktree roots returned by `listLinkedWorktreeRoots` to locate the most recently written cache directory matching the active Turbopack cache version (`getTurbopackCacheVersion()`).

```typescript
function findSeedSource(
  worktreeInfo: GitWorktreeInfo,
  projectDir: string,
  distDir: string,
  version: string
): string | undefined {
  const projectRelToWorktree = path.relative(
    worktreeInfo.worktreeRoot,
    projectDir
  )
  const distRelToProject = path.relative(projectDir, distDir)
  const currentWorktree = path.resolve(worktreeInfo.worktreeRoot)

  // We are going to find the best candidate worktree
  // based on the most recently written cache directory.
  // We only look at our version

  let best: { versionDir: string; commitTimeMs: number } | undefined
  for (const root of [
    worktreeInfo.mainRepoRoot,
    ...listLinkedWorktreeRoots(worktreeInfo.mainRepoRoot),
  ]) {
    if (path.resolve(root) === currentWorktree) continue
    const versionDir = path.join(
      root,
      projectRelToWorktree,
      distRelToProject,
      'cache',
      'turbopack',
      version
    )
    const commitTimeMs = currentCommitTimeMs(versionDir)
    if (commitTimeMs === undefined) continue
    if (!best || commitTimeMs > best.commitTimeMs) {
      best = { versionDir, commitTimeMs }
    }
  }
  return best?.versionDir
}
```
Sources: [packages/next/src/lib/turbopack-cache-seed.ts:65-103](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/lib/turbopack-cache-seed.ts#L65-L103)

The candidacy of each `versionDir` is evaluated by reading the persistence layer metadata file `CURRENT` to extract the `commit_time` epoch timestamp, ensuring only valid, readable JSON cache states are considered as seed sources.

```typescript
// When the cache in `versionDir` was last committed to, in epoch milliseconds, or undefined if
// there is no usable cache there. Read from the `commit_time` the persistence layer records in
// CURRENT.
function currentCommitTimeMs(versionDir: string): number | undefined {
  let commitTime
  try {
    commitTime = JSON.parse(
      fs.readFileSync(path.join(versionDir, 'CURRENT'), 'utf8')
    ).commit_time
  } catch {
    // missing, unreadable, or not valid JSON - treat it as not a seed candidate
    return undefined
  }
  if (typeof commitTime !== 'string') return undefined
  const parsed = Date.parse(commitTime)
  return Number.isNaN(parsed) ? undefined : parsed
}
```
Sources: [packages/next/src/lib/turbopack-cache-seed.ts:105-121](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/lib/turbopack-cache-seed.ts#L105-L121)

> [!NOTE]
> The regular expression `IMMUTABLE_CACHE_FILE` identifies immutable Turbopack persistence artifacts (`.sst`, `.blob`, `.meta`, and `.del`), which are linked via `fs.linkSync` during seeding rather than copied, while mutable files such as `CURRENT` and `LOG` are copied to receive independent inodes.

```typescript
const IMMUTABLE_CACHE_FILE = /\.(sst|blob|meta|del)$/

function seedCacheDir(src: string, dst: string): void {
  const stat = fs.lstatSync(src)
  if (stat.isDirectory()) {
    fs.mkdirSync(dst, { recursive: true })
    for (const name of fs.readdirSync(src)) {
      seedCacheDir(path.join(src, name), path.join(dst, name))
    }
  } else if (IMMUTABLE_CACHE_FILE.test(src)) {
    fs.linkSync(src, dst)
  } else {
    // Mutable/unknown (CURRENT, LOG, …) - copy so it gets its own inode.
    fs.copyFileSync(src, dst)
  }
}
```
Sources: [packages/next/src/lib/turbopack-cache-seed.ts:131-146](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/lib/turbopack-cache-seed.ts#L131-L146)

| Helper Function / Constant | Target File / Module | Purpose |
| :--- | :--- | :--- |
| `turborepoTraceAccess` | `packages/next/src/build/turborepo-access-trace/helpers.ts` | Executes and traces file/module accesses for Turborepo task inputs |
| `writeTurborepoAccessTraceResult` | `packages/next/src/build/turborepo-access-trace/helpers.ts` | Serializes recorded access trace results to disk |
| `TurborepoAccessTraceResult` | `packages/next/src/build/turborepo-access-trace/result.ts` | Represents structured trace outputs across workspace boundaries |
| `seedTurbopackCacheIfNeeded` | `packages/next/src/lib/turbopack-cache-seed.ts` | Coordinates cross-worktree Turbopack cache seeding |
| `IMMUTABLE_CACHE_FILE` | `packages/next/src/lib/turbopack-cache-seed.ts` | Matches immutable persistence files (`.sst`, `.blob`, `.meta`, `.del`) for hardlinking |

Sources: [packages/next/src/build/turborepo-access-trace/index.ts:1-6](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/turborepo-access-trace/index.ts#L1-L6), [packages/next/src/lib/turbopack-cache-seed.ts:11-146](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/lib/turbopack-cache-seed.ts#L11-L146)

## Workspace Root Resolution and Detection

### Algorithmic Workspace Discovery

Next.js and its related codemod and upgrade tooling implement explicit root discovery algorithms to locate monorepo boundaries, package managers, and workspace configurations from any working subdirectory. The build runtime core locates project roots via `findRootDirAndLockFiles` in `packages/next/src/lib/find-root.ts`, which searches upward using `findUp.sync` to evaluate dedicated workspace markers (`pnpm-workspace.yaml`, `lerna.json`) and package manager lockfiles (`pnpm-lock.yaml`, `package-lock.json`, `yarn.lock`, `bun.lock`, `bun.lockb`).

```typescript
const LOCK_FILES = [
  'pnpm-lock.yaml',
  'package-lock.json',
  'yarn.lock',
  'bun.lock',
  'bun.lockb',
]

// Dedicated workspace-root files. pnpm and Lerna declare the root this way.
const WORKSPACE_MARKERS = ['pnpm-workspace.yaml', 'lerna.json']

```
Sources: [packages/next/src/lib/find-root.ts:98-108](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/lib/find-root.ts#L98-L108)

Workspace markers take precedence over ordinary lockfiles to prevent nested package-level lockfiles from incorrectly truncating root detection. The helper `findWorkspaceMarker` checks for workspace configuration files and evaluates `package.json` files for the presence of a `workspaces` array or object field via `hasWorkspacesField`.

```typescript
function hasWorkspacesField(packageJson: string): boolean {
  try {
    return JSON.parse(readFileSync(packageJson, 'utf8')).workspaces != null
  } catch {
    return false
  }
}

function findWorkspaceMarker(directory: string): string | undefined {
  for (const name of WORKSPACE_MARKERS) {
    const markerPath = join(directory, name)
    if (existsSync(markerPath)) {
      return markerPath
    }
  }

  const packageJson = join(directory, 'package.json')
  return hasWorkspacesField(packageJson) ? packageJson : undefined
}
```
Sources: [packages/next/src/lib/find-root.ts:111-129](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/lib/find-root.ts#L111-L129)

> [!NOTE]
> When multiple candidate root markers are discovered ascending the directory tree, traversal halts if a higher parent directory contains no workspace marker once a workspace marker has already been accepted, preventing inner project roots from crossing monorepo boundaries incorrectly.

```typescript
while (true) {
  const lastCandidate = candidates[candidates.length - 1]
  const currentDir = dirname(lastCandidate)
  const parentDir = dirname(currentDir)

  // dirname('/')==='/' so if we happen to reach the FS root (as might happen in a container we need to quit to avoid looping forever
  if (parentDir === currentDir) break

  const nextCandidate = findNextRootCandidate(parentDir)

  if (!nextCandidate) break

  // findNextRootCandidate searches for markers all the way up, so a non-marker
  // here means there is no higher marker: nothing above can extend the root.
  if (foundWorkspaceMarker && !nextCandidate.isWorkspaceMarker) break

  candidates.push(nextCandidate.path)
  foundWorkspaceMarker ||= nextCandidate.isWorkspaceMarker
}

```
Sources: [packages/next/src/lib/find-root.ts:159-178](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/lib/find-root.ts#L159-L178)

### Boundary Enforcement and Codemod Detection

Root candidate acceptance enforces strict boundaries against git repositories, worktrees, and user home directories. `findGitBoundary` detects Git repository or worktree roots, validating worktree references by checking for a `commondir` file inside the git directory.

```typescript
function isGitWorktree(dir: string, gitFile: string): boolean {
  let contents: string
  try {
    contents = readFileSync(gitFile, 'utf8')
  } catch {
    return false
  }

  // Match the behavior in git:
  // https://github.com/git/git/blob/13c7afec212fc97ce257d15601659314c6673d6c/setup.c#L1007-L1018
  const match = /^gitdir: (.+?)[\r\n]*$/s.exec(contents)
  if (!match) return false

  const gitDir = resolve(dir, match[1])
  return existsSync(join(gitDir, 'commondir'))
}
```
Sources: [packages/next/src/lib/find-root.ts:53-68](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/lib/find-root.ts#L53-L68)

If an inferred candidate root extends past a git repository boundary or into the local home directory returned by `findHomeDir()`, resolution terminates and records a `RootBoundary` descriptor to issue configuration warnings.

```typescript
const homeDir = findHomeDir()
const gitBoundary = findGitBoundary(cwd)

const acceptedCandidates: string[] = []
let boundary: RootBoundary | undefined

for (const candidate of candidates) {
  const dir = dirname(candidate)

  // the app's own directory is always a valid root. even if it
  // is the home directory.
  if (dir !== cwd) {
    const resolvedDir = toRealPath(dir)

    // `dir` sits above the repo or worktree that contains the app.
    if (gitBoundary && isStrictAncestor(resolvedDir, gitBoundary.dir)) {
      // add a warning for going beyond a repository
      if (gitBoundary.type === 'repository') {
        boundary = {
          boundary: gitBoundary.dir,
          marker: candidate,
          root: dir,
          type: 'repository',
        }
      }
      break
    }

    // never treat the home directory (or above) as the root.
    if (homeDir && isAncestorOrSelf(resolvedDir, homeDir)) {
      boundary = {
        boundary: homeDir,
        marker: candidate,
        root: dir,
        type: 'home',
      }
      break
    }
  }

  acceptedCandidates.push(candidate)
}
```
Sources: [packages/next/src/lib/find-root.ts:181-222](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/lib/find-root.ts#L181-L222)

Complementary workspace detection in `packages/next-codemod/lib/agents-md.ts` inspects working directories to classify monorepo types and expand glob patterns for package resolution.

```typescript
type WorkspaceType = 'pnpm' | 'npm' | 'yarn' | 'nx' | 'lerna' | null

interface WorkspaceInfo {
  isMonorepo: boolean
  type: WorkspaceType
  packages: string[]
}
```
Sources: [packages/next-codemod/lib/agents-md.ts:455-461](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next-codemod/lib/agents-md.ts#L455-L461)

| Detector / Helper Function | Source Module | Target Markers / Configuration Files |
| :--- | :--- | :--- |
| `findRootDirAndLockFiles` | `packages/next/src/lib/find-root.ts` | `pnpm-workspace.yaml`, `lerna.json`, `package.json`, `pnpm-lock.yaml`, `package-lock.json`, `yarn.lock`, `bun.lock`, `bun.lockb` |
| `findGitBoundary` | `packages/next/src/lib/find-root.ts` | `.git` (directory or worktree pointer file with `commondir`) |
| `detectWorkspace` | `packages/next-codemod/lib/agents-md.ts` | `pnpm-workspace.yaml`, `package.json` (`workspaces`), `lerna.json`, `nx.json` |
| `getPkgManager` | `packages/next-codemod/lib/handle-package.ts` | `package.json` (`packageManager` field), `yarn.lock`, `pnpm-lock.yaml`, `bun.lock`, `bun.lockb`, `package-lock.json` |

Sources: [packages/next/src/lib/find-root.ts:53-129](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/lib/find-root.ts#L53-L129), [packages/next-codemod/lib/agents-md.ts:455-502](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next-codemod/lib/agents-md.ts#L455-L502), [packages/next-codemod/lib/handle-package.ts:56-107](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next-codemod/lib/handle-package.ts#L56-L107)

## Multi-Engine Tooling and Test Orchestration

### Cargo Workspace Configuration and Optimization Profiles

The repository integrates a root `Cargo.toml` workspace managing Rust crates for Turbopack, SWC bindings, and NAPI extensions with resolver version `2`. Workspace members include core orchestration and compilation packages such as `next-api`, `next-build`, `next-core`, `crates/next-napi-bindings`, `crates/wasm`, and all workspace members under `turbopack/crates/*`.

```
[workspace]
resolver = "2"

members = [
  "scripts/send-trace-to-jaeger",
  "crates/next-napi-bindings",
  "crates/wasm",
  "crates/next-api",
  "crates/next-build-test",
  "crates/next-build",
  "crates/next-code-frame",
  "crates/next-core",
  "crates/next-custom-transforms",
  "crates/next-taskless",
  "turbopack/crates/*",
  "turbopack/crates/*/fuzz",
  "turbopack/xtask",
]
```
Sources: [Cargo.toml:1-18](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/Cargo.toml#L1-L18)

Custom Cargo compilation profiles govern development, release, and debugging behaviors across dependencies and size-optimized crates. The `profile.dev` configuration sets `debug = "line-tables-only"` to improve build times, applies `opt-level = 1` to `turbo-persistence` and external dependencies (`"*"`), and enforces `opt-level = 3` for build scripts via `profile.dev.build-override`.

```
[profile.dev]
# https://kobzol.github.io/rust/rustc/2025/05/20/disable-debuginfo-to-improve-rust-compile-times.html
debug = "line-tables-only"

# This crate is particularly sensitive to compiler optimizations
[profile.dev.package.turbo-persistence]
opt-level = 1

# Set the options for dependencies (not crates in the workspace), this mostly impacts cold builds
[profile.dev.package."*"]
opt-level = 1

# Set the settings for build scripts and proc-macros.
[profile.dev.build-override]
opt-level = 3

```
Sources: [Cargo.toml:38-53](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/Cargo.toml#L38-L53)

> [!NOTE]
> Size-optimized crates under `profile.release` target code size reduction (`opt-level = "s"`), specifically compiling Wasmtime, Cranelift, lightningcss, and SWC ecmascript transformation packages to minimize final binary footprints.

```
[profile.release.package.browserslist-rs]
opt-level = "s"

[profile.release.package.cranelift-codegen]
opt-level = "s"

[profile.release.package.handlebars]
opt-level = "s"

[profile.release.package.lightningcss]
opt-level = "s"

# The vendored napi glue for lightningcss; size-optimized like `lightningcss` itself.
[profile.release.package.turbopack-lightningcss-napi]
opt-level = "s"

[profile.release.package.markdown]
opt-level = "s"

[profile.release.package.mdxjs]
opt-level = "s"

[profile.release.package.regalloc2]
opt-level = "s"

[profile.release.package.regex-syntax]
opt-level = "s"

[profile.release.package.reqwest]
opt-level = "s"

[profile.release.package.styled_jsx]
opt-level = "s"

[profile.release.package.swc_css_prefixer]
opt-level = "s"

[profile.release.package.swc_ecma_compat_bugfixes]
opt-level = "s"

[profile.release.package.swc_ecma_compat_es2015]
opt-level = "s"

[profile.release.package.swc_ecma_compat_es2022]
opt-level = "s"

[profile.release.package.swc_ecma_preset_env]
opt-level = "s"

[profile.release.package.swc_ecma_transforms_module]
opt-level = "s"

[profile.release.package.swc_ecma_transforms_proposal]
opt-level = "s"

[profile.release.package.swc_plugin_backend_wasmtime]
opt-level = "s"

[profile.release.package.swc_plugin_runner]
opt-level = "s"

[profile.release.package.wasmtime]
opt-level = "s"

[profile.release.package.wasmtime-internal-cranelift]
opt-level = "s"

```
Sources: [Cargo.toml:94-160](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/Cargo.toml#L94-L160)

| Profile Name | Key Settings & Optimizations | Purpose / Target Components |
| :--- | :--- | :--- |
| `profile.dev` | `debug = "line-tables-only"`, `opt-level = 1` for `turbo-persistence` and `"*"` | Fast local iteration and compile-time reduction |
| `profile.release` | `lto = "thin"`, `codegen-units = 1`, `opt-level = "s"` for specific packages | Production builds with minimized binary size and code duplication |
| `profile.release-with-assertions` | `debug-assertions = true`, `overflow-checks = true`, `lto = false`, `codegen-units = 64` | CI or performance-sensitive testing requiring validation checks |
| `profile.dev-with-debug` | Inherits `dev`, `debug = true` | Local debugging with full debug information |

Sources: [Cargo.toml:38-91](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/Cargo.toml#L38-L91)

### Orchestration Metadata and Test Profiles

Workspace orchestration metadata is configured via `conductor.json`, defining framework setup scripts, worktree default branches (`canary`), and environment flags such as `NEXT_TELEMETRY_DISABLED` and `TURBO_TELEMETRY_DISABLED`. Recommendations advise running `pnpm sweep` to clean Rust build artifacts and utilizing `pnpm test-dev-turbo` for accelerated test execution.

```json
{
  "name": "next.js",
  "description": "Next.js framework development workspace",
  "scripts": {
    "setup": "./.conductor/scripts/setup.sh",
    "run": "./.conductor/scripts/run.sh"
  },
  "worktree": {
    "default_branch": "canary"
  },
  "environment": {
    "NEXT_TELEMETRY_DISABLED": "1",
    "TURBO_TELEMETRY_DISABLED": "1"
  },
  "recommendations": {
    "parallel_agents": 3,
    "notes": [
      "Each worktree uses ~500MB-1GB disk space after build",
      "Run 'pnpm sweep' periodically to clean Rust build artifacts",
      "Use 'pnpm test-dev-turbo' for fastest test iteration",
      "Never run 'pnpm build' while 'pnpm dev' is active (causes corruption)"
    ]
  }
```
Sources: [conductor.json:1-23](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/conductor.json#L1-L23)

Test suites and evaluation pipelines coordinate execution across environments through test configuration harnesses. `run-evals.js` packages the local `next` module and provisions agent evals against baseline and documentation-augmented variants (`baseline` and `agents-md`).

```javascript
const BASE_VARIANTS = [
  {
    suffix: 'baseline',
    imports: `import { installNextJs, installPlaywright, prepareFixture } from '../lib/setup.js'`,
    setup: `await installNextJs(sandbox)\n    await installPlaywright(sandbox)\n    await prepareFixture(sandbox)`,
  },
  {
    suffix: 'agents-md',
    imports: `import { installNextJs, installPlaywright, prepareFixture, writeAgentsMd } from '../lib/setup.js'`,
    setup: `await installNextJs(sandbox)\n    await installPlaywright(sandbox)\n    await prepareFixture(sandbox)\n    await writeAgentsMd(sandbox)`,
  },
]
```
Sources: [run-evals.js:44-55](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/run-evals.js#L44-L55)

The `TestProfile` class in `run-tests.js` captures test behavior identifiers, environment variables, and result caching states. It tracks behavioral variables like `IS_WEBPACK_TEST`, `IS_TURBOPACK_TEST`, `TURBOPACK_DEV`, `TURBOPACK_BUILD`, `BROWSER_NAME`, and `DEVICE_NAME`, while explicitly ignoring operational metadata.

```javascript
class TestProfile {
  // Env vars that always affect test behavior (non-NEXT prefixed).
  static EXTRA_ENV_VARS = [
    'IS_WEBPACK_TEST',
    'IS_TURBOPACK_TEST',
    'TURBOPACK_DEV',
    'TURBOPACK_BUILD',
    'BROWSER_NAME',
    'DEVICE_NAME',
  ]

  // NEXT_* / __NEXT* vars that are operational, not behavioral.
  static IGNORED_VARS = new Set([
    'NEXT_TELEMETRY_DISABLED',
    'NEXT_TEST_JOB',
    'NEXT_JUNIT_TEST_REPORT',
    'NEXT_TEST_PREFER_OFFLINE',
    'NEXT_CI_RUNNER',
    'NEXT_E2E_TEST_TIMEOUT',
    'NEXT_TURBOPACK_IO_CONCURRENCY',
    'NEXT_TEST_PASSED_FILE',
    'NEXT_TEST_BROWSER_WS_ENDPOINT',
    'TURBO_TASKS_AVAILABLE_PARALLELISM',
  ])

  // All key=value pairs identifying this test profile, sorted by key.
  // Used for the diagnostic `log()` output. Computed once at construction
  // from a snapshot of process.env. The actual cache key for the workflow
  // is `input_step_key` (see `.github/workflows/build_reusable.yml`).
  entries
  // NEXT_*/__NEXT* vars that matched the pattern but were ignored.
  ignoredVars
  cachingEnabled

```
Sources: [run-tests.js:23-56](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/run-tests.js#L23-L56)

## Related

- [Project Structure](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/orientation/project-structure)
- [Build Pipeline](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-system/build-pipeline)


## Sitemap

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