# System map — vercel/next.js

> Canonical page: https://codevetter.com/unpack/nextjs/system-map

# System map — vercel/next.js

Scanned commit 2861a364fcbe75fe96b0b9127f9b335edfcf288c (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

A pnpm + Turborepo + Lerna monorepo (`pnpm-workspace.yaml` globs `apps/*`, `packages/*`, `bench/*`, `crates/*/js`, `turbopack/crates/*/js`) layered on top of a single Cargo workspace (`Cargo.toml`) that builds Turbopack, the next-swc transforms, and the napi bindings. The JS entrypoint is `packages/next/src/bin/next.ts`, a Commander program that lazily dynamic-imports one `src/cli/next-*.ts` module per subcommand. At runtime `next dev` forks a child process running `server/lib/start-server.ts`, which boots `server/lib/router-server.ts` (routing, middleware, dev bundler) which in turn lazily loads `server/lib/render-server.ts` → `NextNodeServer` (`server/next-server.ts`) extending the abstract `BaseServer` (`server/base-server.ts`). Storage is the filesystem: `.next/` manifests plus a pluggable `IncrementalCache` / `CacheHandler` layer. Turbopack is reached through napi via `packages/next/src/build/swc/index.ts` wrapping the Rust `Project` type in `crates/next-api/src/project.rs`.
- `packages/next/src/bin/next.ts` is the single published binary (`"bin": {"next": "./dist/bin/next"}`) and registers every subcommand on a `NextRootCommand extends Command`: `build`, `experimental-analyze`, `dev` (isDefault), `export` (hidden), `info`, `start`, `telemetry`, `typegen`, `upgrade`, `experimental-test`, `experimental-request-insights`, and an `internal` group with `trace`, `query-trace`, `post-build`, `upload-trace`, `static-routes-info`, `agent-feedback-instructions`. — [packages/next/src/bin/next.ts#L187-L836](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/bin/next.ts#L187-L836) [packages/next/package.json#L72-L75](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/package.json#L72-L75)
- Each subcommand is code-split behind a dynamic import inside `.action()` (e.g. `import('../cli/next-export.js').then((mod) => mod.nextExport())`), so CLI startup never loads the build or dev-server graph unless that command is invoked. — [packages/next/src/bin/next.ts#L430-L433](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/bin/next.ts#L430-L433)
- `next dev` runs as two processes: the CLI process supervises, and `fork(require.resolve('../server/lib/start-server'))` spawns the actual server with `NEXT_PRIVATE_WORKER=1`, `__NEXT_DEV_SERVER='1'`, `NEXT_PRIVATE_TRACE_ID`, and a `WATCHPACK_WATCHER_LIMIT=20` workaround on darwin; options cross the boundary over IPC messages `nextWorkerReady` → `nextWorkerOptions` → `nextServerReady`. — [packages/next/src/cli/next-dev.ts#L352-L452](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/cli/next-dev.ts#L352-L452) [packages/next/src/server/lib/start-server.ts#L648-L673](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/server/lib/start-server.ts#L648-L673)
- `startServer()` in `server/lib/start-server.ts` creates the raw `http`/`https` server (https only when `--experimental-https` supplies a self-signed cert) and installs a `requestListener` that awaits a `handlersPromise` before delegating to the router-server handler, so the socket is listening before the bundler is ready. — [packages/next/src/server/lib/start-server.ts#L186-L292](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/server/lib/start-server.ts#L186-L292)
- `server/lib/router-server.ts#initialize()` is the real runtime boundary: it builds the filesystem checker, optionally instantiates `setupDevBundler` + `DevBundlerService` in dev, wires `renderServer.instance = require('./render-server')`, and returns `{ requestHandler, upgradeHandler }` used by both `next dev` and `next start`. — [packages/next/src/server/lib/router-server.ts#L130-L306](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/server/lib/router-server.ts#L130-L306) [packages/next/src/server/lib/router-server.ts#L904-L1110](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/server/lib/router-server.ts#L904-L1110)
- `BaseServer` (3459 lines) is the abstract render core; its `protected abstract` surface — `findPageComponents`, `getPagesManifest`, `getPrerenderManifest`, `renderHTML`, `getIncrementalCache`, `handleUpgrade`, `getMiddleware` — is implemented by `NextNodeServer` for Node and by a separate web/edge server under `packages/next/src/server/web/`. — [packages/next/src/server/base-server.ts#L358-L441](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/server/base-server.ts#L358-L441) [packages/next/src/server/next-server.ts#L185-L360](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/server/next-server.ts#L185-L360)
- Build is one giant traced function: `build()` in `packages/next/src/build/index.ts` (4815 lines) wraps everything in a `trace('next-build')` span, loads config, runs `discoverRoutes`/`createPagesMapping`, then branches to either `turbopackBuild(telemetry)` or `webpackBuild(useBuildWorker, [...])`, and finally writes `ROUTES_MANIFEST`, `PRERENDER_MANIFEST`, `APP_PATH_ROUTES_MANIFEST` and friends via a shared `writeManifest<T>()` helper. — [packages/next/src/build/index.ts#L1058-L1120](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/build/index.ts#L1058-L1120) [packages/next/src/build/index.ts#L1810-L1860](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/build/index.ts#L1810-L1860) [packages/next/src/build/index.ts#L664-L810](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/build/index.ts#L664-L810)
- Turbopack is consumed through napi: `packages/next/src/build/swc/index.ts` (1905 lines) defines a `ProjectImpl implements Project` class that forwards to native calls like `binding.projectEntrypointsSubscribe`, `binding.projectWriteAllEntrypointsToDisk`, `binding.projectClientHmrEvents`, and `binding.projectGetSourceMap`, all backed by `crates/next-api/src/project.rs`'s `ProjectContainer`/`Project` turbo-tasks types. — [packages/next/src/build/swc/index.ts#L683-L835](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/build/swc/index.ts#L683-L835) [crates/next-api/src/project.rs#L448-L1045](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/crates/next-api/src/project.rs#L448-L1045)
- The Rust workspace excludes `rspack/crates/binding` and tunes profiles aggressively — `turbo-persistence` gets `opt-level = 1` even in dev, release uses `lto = "thin"` — indicating the persistence layer and cold-build time are known hot spots. — [Cargo.toml#L1-L60](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/Cargo.toml#L1-L60)
- Storage is layered: `IncrementalCache` (`server/lib/incremental-cache/index.ts`) picks a handler from `globalThis[Symbol.for('@next/cache-handlers')].FetchCache` or falls back to `FileSystemCache`, which writes under `serverDistDir/../cache/fetch-cache`, `serverDistDir/pages`, and `serverDistDir/app`. — [packages/next/src/server/lib/incremental-cache/index.ts#L143-L220](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/server/lib/incremental-cache/index.ts#L143-L220) [packages/next/src/server/lib/incremental-cache/file-system-cache.ts#L460-L480](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/server/lib/incremental-cache/file-system-cache.ts#L460-L480)
- Build/test commands are defined in the root `package.json`: `pnpm build` (`turbo run build`), `pnpm build-all` (adds `build-native-auto`), `pnpm --filter=next dev` for the taskr watch build, `pnpm test-unit`, and a 20-entry matrix of `test-{dev,start,deploy}-{webpack,turbo,rspack}[-experimental]` scripts that all shell into `scripts/run-jest.sh`. — [package.json#L8-L70](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/package.json#L8-L70) [scripts/run-jest.sh#L1-L60](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/scripts/run-jest.sh#L1-L60)
- Turborepo caches `build`/`dev` on `dist/**` outputs and declares a `pack-for-isolated-tests` task producing `packed.tgz`, which is how integration tests install a real tarball of `next` rather than a symlinked workspace copy. — [turbo.json#L6-L30](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/turbo.json#L6-L30) [packages/next/package.json#L86-L88](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/package.json#L86-L88)
- The `next` package vendors its own dependencies at build time: `packages/next/taskfile.js` (3140 lines) declares an `externals[...]` map and one `ncc_*` task per bundled dep (`node-html-parser`, `@vercel/routing-utils`, `busboy`, `@babel/runtime`, …), all remapped to `next/dist/compiled/*`. — [packages/next/taskfile.js#L100-L200](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/taskfile.js#L100-L200) [jest.config.js#L20-L26](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/jest.config.js#L20-L26)
- Deployment shape for downstream users is pluggable via `config.adapterPath` (defaulting to `process.env.NEXT_ADAPTER_PATH`): after the build, `handleBuildComplete()` dynamic-imports that module and hands it an `AdapterOutputs` description of every route, so hosting platforms can consume the build without reading `.next` internals. — [packages/next/src/server/config-shared.ts#L1848](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/server/config-shared.ts#L1848) [packages/next/src/server/config-shared.ts#L2356](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/server/config-shared.ts#L2356) [packages/next/src/build/adapter/build-complete.ts#L499-L660](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/build/adapter/build-complete.ts#L499-L660) [packages/next/src/build/index.ts#L4594](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/packages/next/src/build/index.ts#L4594)
- CI is GitHub Actions with a reusable-workflow pattern: `build_and_test.yml` fans out to `build_reusable.yml` for `build-native`, `build-native-windows`, `build-next`, `lint`, `types-and-precompiled`, `test-cargo-unit`, `test-cargo-unit-miri`, `rust-check`, and `rustdoc-check`, each passing an `afterBuild:` shell body and a `stepName`. — [.github/workflows/build_and_test.yml#L129-L380](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/.github/workflows/build_and_test.yml#L129-L380) [.github/workflows/build_reusable.yml](https://github.com/vercel/next.js/blob/2861a364fcbe75fe96b0b9127f9b335edfcf288c/.github/workflows/build_reusable.yml)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
