Relevant source files
The following files were used as context for generating this wiki page:
- pnpm-workspace.yaml
- packages/next-codemod/lib/agents-md.ts
- packages/next/src/build/index.ts
- packages/next/taskfile.js
- package.json
- turbo.json
- packages/next/src/build/adapter/build-complete.ts
- packages/create-next-app/templates/index.ts
- conductor.json
- packages/next/src/build/swc/index.ts
- packages/next/src/build/turborepo-access-trace/index.ts
- Cargo.toml
- run-evals.js
- packages/next/src/build/webpack/loaders/next-app-loader/index.ts
- packages/next-codemod/turbo.json
- socket.yaml
- packages/next-codemod/bin/upgrade.ts
- packages/next/turbo.json
- packages/next-codemod/lib/handle-package.ts
- packages/next/src/lib/turbopack-cache-seed.ts
- packages/next/src/lib/find-root.ts
- packages/next/package.json
- run-tests.js
- packages/next/src/server/lib/chrome-devtools-workspace.ts
- packages/next/src/build/utils.ts
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, Cargo.toml:1-18
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
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, package.json:302-305
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
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
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
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, turbo.json:34-34
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
Note
Tasks prefixed with //# execute exclusively at the root workspace level rather than propagating across individual package members.
Sources: turbo.json:27-32
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 UI compilation before executing package assembly.
{
"$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
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.
{
"$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
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, packages/next-codemod/turbo.json:20-23
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.
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
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 |
shared_esm | `src/shared/**/*.+(js | ts | tsx)` | dist/esm/shared |
server_wasm | src/server/**/*.+(wasm) | dist/server | Direct copy | — |
experimental_testing | `src/experimental/testing/**/!(*.test).+(js | ts | tsx)` | dist/experimental/testing |
experimental_testmode | `src/experimental/testmode/**/!(*.test).+(js | ts | tsx)` | dist/experimental/testmode |
Sources: packages/next/taskfile.js:2830-2904
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
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, packages/next/package.json:83-96
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, packages/next/package.json:83-104
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
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.
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
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.
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
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()).
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
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.
// 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
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.
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
| 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, packages/next/src/lib/turbopack-cache-seed.ts:11-146
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).
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
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.
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
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.
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
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.
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
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.
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
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.
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
| 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, packages/next-codemod/lib/agents-md.ts:455-502, packages/next-codemod/lib/handle-package.ts:56-107
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
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
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
| 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
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.
{
"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
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).
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
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.
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
Related
On This Page
OverviewPNPM Workspace Layout and BoundariesWorkspace Directory Patterns and Glob MappingsPackage Manager and Security RestrictionsExcluded Dependencies and OverridesTurborepo Task Pipeline CoordinationRoot Task Topologies and Global EnvironmentPackage-Specific Task OverridesInternal Packaging and Task AutomationTask Automation and Compilation PipelinesPackage Metadata and Script DefinitionsTurborepo Access Tracing and CachingCache Seeding and Worktree ResolutionWorkspace Root Resolution and DetectionAlgorithmic Workspace DiscoveryBoundary Enforcement and Codemod DetectionMulti-Engine Tooling and Test OrchestrationCargo Workspace Configuration and Optimization ProfilesOrchestration Metadata and Test ProfilesRelated