vercel/next.js
turbopack-ecmascript
JavaScript / TypeScript / JSX / TSX support for Turbopack. Parses, analyzes, transforms, and emits the language. Where Turbopack's heaviest single source file lives: lib.rs at 118,566 lines (mostly because it contains the central EcmascriptModuleAsset type with hundreds of methods plus a long tail of conditional compilation paths).
Source: turbopack/crates/turbopack-ecmascript/src/.
Pipeline
graph LR
File[Source file] --> Parse[parse.rs<br/>swc parser]
Parse --> Ast[Ast]
Ast --> Analyze[analyzer/]
Analyze --> Refs[references/]
Refs --> Transform[transform/<br/>SWC visitors]
Transform --> Codegen[swc_ecma_codegen]
Codegen --> Code[Code + source map]
Code --> Chunk[chunk/]
Chunk --> Output[OutputAsset]Major components
lib.rs (119 KB)
The central file. Defines:
EcmascriptModuleAsset— the module type for JS/TS files.EcmascriptModuleAssetType— the distinction between.js,.ts,.jsx,.tsx, etc.EcmascriptOptions— per-asset options (transforms, target, source-type).- All the wiring that turns a parsed file into a fully-resolved set of references and a chunk-ready item.
parse.rs (29 KB)
Parses source files via swc_ecma_parser. The result is cached by content hash so identical files (e.g., common dependencies) parse once.
analyzer/
Static analysis. Walks the AST to identify imports, exports, dynamic imports, require() calls, import.meta, top-level awaits, side effects, and assigned globals. The analyzer produces a structured representation that subsequent stages consume.
references/
Builds typed reference values for each thing the analyzer found:
EsmAssetReference,CommonJsAssetReference,RawAssetReference, etc. (defined here, not in turbopack-core).- ES module exports/imports.
- Dynamic imports as
AsyncAssetReference. node:-prefixed builtins.
transform/
SWC visitor wrappers. Common transforms: TypeScript stripping, JSX desugaring, decorator handling, class-property lowering. These are SWC's standard transforms; Next.js's specific ones (server actions, fonts, RSC) live in crates/next-custom-transforms/ and plug in via turbopack-ecmascript-plugins.
chunk/
The JS-specific chunker. Emits chunks shaped as:
- A "modules.js" preamble defining the runtime.
- Per-module IIFEs keyed by module id.
- A chunk loader and HMR support.
The runtime side lives in turbopack/crates/turbopack-ecmascript-runtime/ (see below).
tree_shake/
Module-level tree-shaking via subgraph splitting. Each export becomes its own subgraph that downstream chunks can pull selectively. More aggressive than rope-based DCE.
side_effect_optimization/
Marks modules as side-effect-free per package.json's sideEffects field. Modules without side effects can be eliminated entirely if no exports are used.
webpack/
Webpack-compatibility quirks: require.context, AMD-style define(), and a few builtins.
worker_chunk/ and async_chunk/
Special chunk shapes for Web Workers and dynamic imports.
manifest/
Manifest-chunk emission — a chunk type that's just a JSON manifest of its members (used by the runtime to defer-load).
text/
?raw import support — load a file as a string at build time.
webpack/runtime / worker_chunk/
Targets for Web Workers and webpack-style runtime.
merged_module.rs
Module merging when chunks contain multiple ESM modules that can be inlined together.
magic_identifier.rs
Helpers for the __turbopack_* runtime identifier set used in generated code.
Source maps
source_map.rs and swc_comments.rs thread source maps through every transform. Each transform pass appends its own mapping segment so the final source map represents the full chain.
Minify
minify.rs wraps swc_ecma_minifier. The minifier runs as a separate #[turbo_tasks::function] so its output is cached.
Annotations
annotations.rs reads framework-significant comments like /* @__PURE__ */ and /* @next-no-bundle */.
Path visitor
path_visitor.rs walks AST paths to build module-relative identifiers used in references and exports.
Runtime
turbopack/crates/turbopack-ecmascript-runtime/ is not Rust code — it's the JavaScript runtime that ships inside compiled chunks. Hand-written and embedded into the binary via include_str!. Implements module loading, HMR client, async chunk loading, and the __turbopack_* global helpers.
Plugins
turbopack/crates/turbopack-ecmascript-plugins/ is the extension point. Custom SWC visitors register here. Next.js plugs in next-custom-transforms through this layer.
HMR protocol
turbopack/crates/turbopack-ecmascript-hmr-protocol/ defines the wire format for HMR messages between dev server and browser.
Integration points
- Consumed by every Next.js entry compiler in
crates/next-api/src/app.rsandcrates/next-api/src/pages.rs. - Composes with
turbopack-css,turbopack-image, etc., when modules import non-JS assets. - Hosts Next.js's SWC visitors via
turbopack-ecmascript-plugins.
Key source files
| File | Purpose |
|---|---|
turbopack/crates/turbopack-ecmascript/src/lib.rs |
The module type and most of the wiring |
turbopack/crates/turbopack-ecmascript/src/parse.rs |
SWC parser |
turbopack/crates/turbopack-ecmascript/src/analyzer/ |
Static analysis |
turbopack/crates/turbopack-ecmascript/src/references/ |
Typed references |
turbopack/crates/turbopack-ecmascript/src/transform/ |
SWC visitor wrappers |
turbopack/crates/turbopack-ecmascript/src/chunk/ |
JS chunker |
turbopack/crates/turbopack-ecmascript/src/tree_shake/ |
Subgraph-level tree shaking |
turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/ |
sideEffects-aware DCE |
turbopack/crates/turbopack-ecmascript/src/webpack/ |
webpack-compat quirks |
turbopack/crates/turbopack-ecmascript/src/source_map.rs |
Source map chaining |
turbopack/crates/turbopack-ecmascript/src/minify.rs |
swc-minifier wrapper |
turbopack/crates/turbopack-ecmascript-runtime/ |
Hand-written JS runtime |
turbopack/crates/turbopack-ecmascript-plugins/ |
Plugin extension point |
turbopack/crates/turbopack-ecmascript-hmr-protocol/ |
HMR wire protocol |
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.