vercel/next.js
next-api
Purpose
next-api is the public crate API surface for Next.js's Rust pipeline. It exposes a Project abstraction that the napi bindings (and the wasm wrapper) call to:
- Open a project at a given path with given config.
- Enumerate App Router and Pages Router entries.
- Compile and emit chunks for an entry.
- Produce manifests (
build-manifest.json,app-build-manifest.json,prerender-manifest.json,nft.json,server-reference-manifest.json,client-reference-manifest.json, etc.). - Stream HMR updates for development.
Source: crates/next-api/src/. Heaviest files: project.rs (93 KB), app.rs (87 KB), pages.rs (70 KB), nft_json.rs (33 KB), module_graph.rs (33 KB).
The Project abstraction
graph TD
Open[Project::new<br/>open project] --> Project[Project]
Project --> Entries[App + Pages entrypoints]
Project --> Compile[Compile entry]
Project --> Manifests[Generate manifests]
Project --> Hmr[HMR subscriptions]
Entries --> AppRoutes[per app route]
Entries --> PagesRoutes[per pages route]
Entries --> Middleware[middleware]
Entries --> Instrumentation[instrumentation]The Project struct is turbo_tasks-aware — that means everything it returns is incrementally cached and recomputed only when its inputs change.
File breakdown
project.rs (93 KB)
The biggest file in the crate. Contains the Project type, its construction, and its top-level methods. Each method returns a Vc<...> (virtual computation) so the result is memoized across builds.
Key methods:
| Method | Returns |
|---|---|
entrypoints() |
Entrypoints struct with app + pages + middleware |
app_project() |
The App Router subproject |
pages_project() |
The Pages Router subproject |
middleware() |
Middleware entry, if defined |
instrumentation() |
Instrumentation entry, if defined |
client_relative_path() |
URL path that client assets serve from |
node_root() |
Output root for Node bundles |
client_chunking_context() |
Chunking context for client bundles |
server_chunking_context() |
Chunking context for server bundles |
app.rs (87 KB)
Walks the App Router structure (using app_structure.rs from next-core) and produces per-route entries: page, layout, error boundary, loading boundary, route handler. Each entry yields client, server, and edge bundles as appropriate.
pages.rs (70 KB)
The Pages Router equivalent. Produces per-page entries, plus the special _app, _document, _error entries.
module_graph.rs (33 KB)
Computes the module graph for an entry: which modules transitively import which. Used to:
- Build manifests of client references and server actions.
- Drive nft.json file tracing.
- Compute chunk shapes.
nft_json.rs + next_server_nft.rs (33 KB + 14 KB)
Per-route file traces. The Node File Tracer (nft) determines which files at which paths each compiled route depends on — a hosting platform reads the per-route nft.json to know what to ship.
server_actions.rs (20 KB)
Tracks which server actions exist in the project, what file each was compiled from, and the action ID (a stable hash) the runtime uses to look them up. Output goes to server-reference-manifest.json.
middleware.rs + instrumentation.rs
Detect, compile, and trace middleware (middleware.ts) and instrumentation (instrumentation.ts) files.
Manifest helpers
asset_hashes_manifest.rs/routes_hashes_manifest.rs/project_asset_hashes_manifest.rs— content-hash manifests.loadable_manifest.rs— thereact-loadable-manifest.jsonfornext/dynamic.sri_manifest.rs— Subresource Integrity hashes.client_references.rs— RSC client reference manifest.dynamic_imports.rs— dynamic-import tracking.
versioned_content_map.rs
A versioned in-memory map used by HMR to track per-revision content. When a file changes, the map version bumps and dependent computations invalidate.
route.rs, paths.rs, entrypoints.rs
Public types: Route, RoutePath, Entrypoints. These are the shapes that flow back to the JavaScript side via napi.
How JavaScript calls in
graph LR
JS[packages/next/src/build/turbopack-build/] --> Napi[next-napi-bindings]
Napi --> ProjectNew[Project::new]
ProjectNew --> Project
JS --> Napi2[napi calls per entrypoint]
Napi2 --> Compile[Compile entry / read chunks]
Compile --> WriteFiles[write to .next/server, .next/static]Every public method on Project has a matching napi binding in crates/next-napi-bindings/. The JS side calls a binding, gets a stream of events, and writes the output to disk.
HMR
Project::hmr_events() returns a stream of update messages keyed by entry. The dev hot reloader (hot-reloader-turbopack.ts) subscribes to this stream and forwards updates to connected browsers.
Integration points
- Consumed by
crates/next-napi-bindingsandcrates/wasm. - Calls into
crates/next-corefor config and structure. - Calls into
turbopack-*crates for the actual bundling. - Outputs manifests consumed by packages/next at runtime.
Entry points for modification
- To add a new manifest: write a new
*_manifest.rsfile and wire it intoProject. - To add a new entry kind: add to
app.rsorpages.rsplus update the napi binding. - To change how chunks emit:
project.rschunking context methods. - To track new metadata in modules:
module_graph.rs.
Key source files
| File | Purpose |
|---|---|
crates/next-api/src/lib.rs |
Crate entry |
crates/next-api/src/project.rs |
The Project type |
crates/next-api/src/app.rs |
App Router entry compilation |
crates/next-api/src/pages.rs |
Pages Router entry compilation |
crates/next-api/src/module_graph.rs |
Module graph computation |
crates/next-api/src/nft_json.rs |
nft.json producer |
crates/next-api/src/server_actions.rs |
Server actions registry |
crates/next-api/src/middleware.rs |
Middleware compilation |
crates/next-api/src/route.rs |
Route types exposed to JS |
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.