CodeVetter
← All unpacks
CodeVetter · Repo Unpack evidence

vercel/next.js

Scanned commit 2861a364fc dated 2026-09-22 — last upstream commit. Generated by codevetter 1.12.0 on 2026-09-22.

github.com/vercel/next.js ↗ · 4000 files · 10.7 MB · scan capped

Next.js Getting Started Used by some of the world's largest companies, Next.js enables you to create full-stack web applications by extending the latest React features, and integrating powerful Rust-based JavaScript tooling for the fastest builds.

Deep analysis by claude-opus-5 via the claude CLI on 2026-09-22 (513s) — every claim below links to its cited source files.

Overview

This is the `vercel/next.js` monorepo at canary `16.4.0-canary.38` — the Next.js React framework itself, plus the Rust Turbopack bundler (vendored as a git subtree under `turbopack/`), the SWC-based native transform crates under `crates/`, and ~20 sibling npm packages (create-next-app, eslint-plugin-next, next-codemod, font, third-parties, next-rspack). The published `next` package is a dual-runtime system: a Node.js router/render server plus an edge-runtime variant, driven by a Commander-based CLI (`next dev|build|start|typegen|upgrade|experimental-test|…`) and fed by either Turbopack (default) or webpack/rspack. What is distinctive is the sheer test-matrix machinery: every integration test runs across three modes (dev/start/deploy) × three bundlers (turbo/webpack/rspack) × an experimental `cacheComponents` axis, orchestrated by `scripts/run-jest.sh` and a custom `@gate` pragma transformer. It is a framework maintained for millions of downstream apps, so nearly every subsystem is an extension point with a stability contract.

System map

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`.

All 15 system map claims →

Feature catalog

User-facing surface splits four ways: the `next` CLI subcommands, the runtime request-handling features (App Router, Pages Router, middleware/proxy, server actions, image optimization, RSC prefetching), the sibling npm packages (create-next-app, eslint-plugin-next, codemods, fonts, third-parties, bundle-analyzer UI), and a dev-time developer-experience layer (dev overlay, MCP server, request insights, typegen). Nearly every experimental capability is gated behind a key in `ExperimentalConfig` and mirrored into bundles by `define-env.ts`. Documentation is itself a product: 1153 markdown files including `docs/01-app` + `docs/02-pages` and 258 `errors/*.mdx` pages that the dev overlay deep-links into.

All 15 feature catalog claims →

Data flow

A request enters at the Node `http.Server` in `start-server.ts`, is immediately sanitised by `filterInternalHeaders()` (which deletes a fixed `INTERNAL_HEADERS` list so clients cannot forge `x-middleware-rewrite`, `x-matched-path`, etc.), then flows through the router-server's `resolveRoutes` pipeline (headers → redirects → middleware → beforeFiles → filesystem → afterFiles → dynamic routes → fallback), and only then crosses into the render server. Inside `BaseServer.handleRequest` the request is wrapped in an OTEL span and per-request metadata is attached via `addRequestMeta`, after which render state is carried in AsyncLocalStorage (`workAsyncStorage`, `workUnitAsyncStorage`) rather than threaded through arguments. Output is a `RenderResult` piped to the socket, with cacheable results passing through `ResponseCache` → `IncrementalCache` → a `CacheHandler`. Build-time data flows the other direction: source files → route discovery → bundler (Turbopack over napi, or webpack) → `.next/*-manifest.json` → read back by `setupFsCheck` at server boot.

All 14 data flow claims →

Behavior traces

Three flows dominate the codebase. (1) Dev startup: CLI parse → fork → HTTP listen → router-server init → dev bundler → render server lazy init. (2) A production request: socket → header filtering → route resolution → `BaseServer.handleRequest` → route module render → response cache → pipe. (3) A production build: config load → route discovery → bundler compile → static generation → manifests → trace collection → adapter callback. Each is traceable through named functions, and each is instrumented with a `trace()`/OTEL span so the sequence is visible in `.next/trace`.

All 15 behavior traces claims →

Testing signals

Jest 29 is the single test runner for JS, configured through `next/jest` itself (dogfooding) in the root `jest.config.js`, with `rootDir: 'test'` plus extra roots into `packages/next/src`, `packages/next-codemod`, `packages/font/src`, `packages/next-routing`, and `packages/eslint-plugin-internal`. Integration coverage is very large — roughly 1183 test files in `test/e2e`, 375 in `test/production`, 314 in `test/development`, 116 in `test/unit` — and every one of them runs under a mode × bundler × experimental-axis matrix selected by env vars in `scripts/run-jest.sh`. Rust has its own lane (`test-cargo-unit`, `test-cargo-unit-miri`, `rust-check`, `rustdoc-check`) in CI. The notable gap is that the harness itself, the CI orchestration in `run-tests.js`, and the deploy mode are lightly covered by anything other than running them.

All 15 testing signals claims →

Risk map

The biggest blast-radius surfaces are the header-filtering allowlist, the dev-server origin guard, the Server Actions CSRF check, the image optimizer's SSRF path, and the PR-adoption script that grants contributor code access to CI secrets. Structurally, `app-render.tsx` (10,768 lines), `build/index.ts` (4,815) and `base-server.ts` (3,459) are single files that concentrate enormous behaviour and are the natural home of regressions. There is also a large amount of implicit coupling via global symbols, `process.env.__NEXT_*` compile-time constants, and an env-var-driven test matrix, all of which make 'works locally' a weak signal unless the exact CI env is mirrored.

All 16 risk map claims →

Extension points

Next.js is built to be extended at five distinct seams: the CLI command table, the config schema + `define-env` pipeline for feature flags, the `RouteModule` class hierarchy for new route kinds, the `CacheHandler` / adapter interfaces for hosting and storage backends, and the test-harness registries (`@gate` conditions, bundler manifests). The repo also formalises extension of the *agent* workflow itself through `.agents/skills/`, with a meta-skill for authoring new ones.

All 14 extension points claims →

Contributor handoff

Read `AGENTS.md` first — `CLAUDE.md` is a symlink to it, and it encodes the non-obvious rules an agent will otherwise get wrong (watch-mode-before-editing, mode-specific test scripts, the PR-description policy for fork contributions, the internal-header security review rule). Work in a throwaway git worktree rather than the user's checkout. Expect slow feedback loops: a full `pnpm build-all` is minutes, `pnpm --filter=next build` ~60s, `pnpm --filter=next types` ~10s, and a single e2e file can take minutes because it installs a real tarball. The dominant trap is the env-var matrix: the same test can pass under webpack and fail under Turbopack, or pass plainly and fail under `__NEXT_CACHE_COMPONENTS=true`.

All 16 contributor handoff claims →

Languages

LanguageFilesShare of source
TypeScript1257348%
JavaScript1197446%
JSON1675docs/config
Markdown1313docs/config
Rust10504%
CSS761docs/config
Sass2161%
YAML111docs/config

Start reading here

Probable source entrypoint: Cargo.toml — inferred from the directory tree and manifest, not the upstream docs.

Source roots

crates/ (434 files) packages/ (433 files)

Repository structure

Top-level pathFiles
crates/434
evals/433
packages/433
turbopack/433
examples/433
test/433
docs/433
bench/317

Docs found: AGENTS.mdCLAUDE.mdcontributing.mdlicense.mdreadme.md

Package

Cargo.toml — , 0 declared dependencies.

CI & config entrypoints

Structural health signals

Average score 7.1/10 across 96 analyzed source files; 24 hotspots surfaced.

These are deterministic review leads — size, churn, and structural signals — not proof of a bug in this project.

Recent history