vercel/next.js
Dependencies
The framework's dependency story is unusual: the runtime ships 141 vendored packages (compiled into a single distribution), and the user-visible dependencies block in packages/next/package.json is intentionally tiny.
Vendored packages
packages/next/src/compiled/ contains 141 third-party packages bundled into the framework. Each is built into a single file (or small set of files) via @vercel/ncc with the recipes in taskfile.js.
Why vendor:
- Lock the runtime to a specific version, immune to user
node_modulesresolution. - Avoid pulling many tiny packages into user
node_modules. - Ship the framework as a single self-contained artifact.
Major vendored packages:
| Package(s) | Role |
|---|---|
react, react-dom (+ canary, experimental) |
The bundled React the framework ships |
react-server-dom-webpack, react-server-dom-turbopack (+ experimental) |
RSC over webpack and Turbopack |
webpack |
The webpack bundler |
acorn |
JS parser for static analysis |
babel, @babel/* |
The babel toolchain (still used in places) |
@edge-runtime/* |
Edge runtime sandbox |
@vercel/nft |
Node File Tracer |
@vercel/og |
OG image generation |
@modelcontextprotocol/sdk |
MCP SDK for IDE integration |
@mswjs/interceptors |
Test-mode HTTP interceptors |
terser, cssnano-simple |
Minifiers |
zod, zod-validation-error |
Config schema validation |
busboy |
Multipart form parsing for server actions |
path-to-regexp |
Route pattern matching |
picomatch |
Glob matching |
comment-json |
JSON-with-comments for tsconfig.json |
jest-worker |
Worker pool primitive |
tar |
Tarball extraction (codemods, examples) |
ua-parser-js |
User-agent parsing |
watchpack |
File watching |
| 100+ more | Browserify polyfills, http helpers, css-loader, etc. |
Real (non-vendored) dependencies
The user-installed dependencies in packages/next/package.json:
"dependencies": {
"@next/env": "16.3.0-canary.5",
"@swc/helpers": "0.5.15",
"baseline-browser-mapping": "^2.9.19",
"caniuse-lite": "^1.0.30001579",
"postcss": "8.5.10",
"styled-jsx": "5.1.6"
}Six packages. The reasoning per package:
@next/env— separate so it can be loaded standalone (used by user code that wants.envparsing without the full framework).@swc/helpers— runtime helpers for SWC-compiled code; can't be vendored because user bundles need to resolve them too.baseline-browser-mapping,caniuse-lite— large datasets, refresh frequently, easier as deps.postcss— stays user-resolvable so user PostCSS plugins can hook in.styled-jsx— transitive runtime dep. User code canimport 'styled-jsx'directly.
Optional dependency
"optionalDependencies": {
"sharp": "^0.34.5"
}sharp is the native image-resizing library used by the image optimizer. Optional because it has prebuilt binaries for many platforms but not all; on platforms without sharp the optimizer falls back to a wasm path.
Peer dependencies
"peerDependencies": {
"@opentelemetry/api": "^1.1.0",
"@playwright/test": "^1.51.1",
"babel-plugin-react-compiler": "*",
"react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
"react-dom": "...",
"sass": "^1.3.0"
}react and react-dom are peer dependencies even though the framework vendors copies of them. The vendored copy is only used internally; user code resolves their own copy. Both must be compatible.
@playwright/test is the framework's experimental test-mode integration.
babel-plugin-react-compiler is the React Compiler, optional.
@opentelemetry/api enables the framework's OTel spans when the user installs it.
sass enables .scss files when the user installs it.
Root devDependencies
The repo's root package.json lists devDependencies for the workspace itself: jest, prettier, typescript, eslint, playwright, tsx, lerna, turbo, etc. These are repo tooling, not shipped to users.
A few of note:
turbo: 2.9.4— the Turborepo build orchestrator (different from Turbopack).lerna: 9.0.3— package management.pnpm: 10.33.0(inpackageManager) — package manager.typescript: 6.0.2— typecheck the workspace.
Patches
Several upstream packages have patches applied via pnpm's patch mechanism:
"patchedDependencies": {
"webpack-sources@3.2.3": "patches/webpack-sources@3.2.3.patch",
"stacktrace-parser@0.1.10": "patches/stacktrace-parser@0.1.10.patch",
"@types/node@20.17.6": "patches/@types__node@20.17.6.patch",
"taskr@1.1.0": "patches/taskr@1.1.0.patch",
"minizlib@3.1.0": "patches/minizlib@3.1.0.patch",
"http-proxy@1.18.1": "patches/http-proxy@1.18.1.patch",
"web-vitals@4.2.1": "patches/web-vitals@4.2.1.patch",
"@rspack/core@1.6.7": "patches/@rspack__core@1.6.7.patch",
"@modelcontextprotocol/sdk": "patches/@modelcontextprotocol__sdk.patch",
"@vercel/blob": "patches/@vercel__blob.patch",
"postcss-scss": "patches/postcss-scss.patch"
}Each patch lives in patches/. Reasons vary (upstream bug fixes pending merge, monkey-patch behavior change). When upstream merges, drop the patch.
Vendoring workflow
To update a vendored package:
- Edit the version under
packages/next/package.jsondevDependencies. - Run
pnpm install. - Re-run the vendoring task (pnpm runs ncc as part of the build).
- Diff the output under
packages/next/src/compiled/and commit.
Some vendored packages have build scripts in packages/next/taskfile.js that customize what gets bundled (e.g., excluding test files, applying additional transforms).
React vendoring
React occupies a special place. The framework vendors:
react,react-dom,react-is(canary release pinned via thereactdep alias)react-experimental,react-dom-experimental(separate folder, experimental release)react-server-dom-webpack,react-server-dom-turbopack(RSC bridges, both stable + experimental)scheduler,scheduler-experimental
The exact pinned versions live in the repo's root package.json under pnpm.overrides:
"react": "npm:react@19.3.0-canary-da9325b5-20260417",
"react-dom": "npm:react-dom@19.3.0-canary-da9325b5-20260417",
"scheduler": "npm:scheduler@0.28.0-canary-da9325b5-20260417"Updates use pnpm sync-react (which calls scripts/sync-react.js) to fetch the latest canary build and update all references.
Why so much vendoring?
Two main reasons:
- Reproducible runtime: regardless of what user code installs, the framework's behavior depends only on what the framework ships.
- Smaller user
node_modules: a singlenextpackage replaces what would otherwise be 100+ packages.
Key paths
| Path | What |
|---|---|
packages/next/src/compiled/ |
All vendored packages |
packages/next/package.json |
Real deps + devDeps |
packages/next/taskfile.js |
Vendoring recipes |
package.json (root) |
Workspace + pnpm overrides |
patches/ |
Patches applied via pnpm |
scripts/sync-react.js |
React-version sync |
scripts/install-native.mjs |
postinstall: pick platform @next/swc-{platform} |
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.