Bun implements a high-performance module system that unifies ES Modules (ESM) and CommonJS (CJS). It provides a native-code resolver for mapping import specifiers to file paths, a plugin system for custom loading logic, and a multi-layered caching strategy to minimize startup latency.
Key Components:
tsconfig.json paths. src/resolver/resolver.zig1-11require() of ESM and import of CJS, handling both within a unified registry.package.json fields including exports, imports, browser, and sideEffects. src/resolver/package_json.zig21-115.ts, .tsx, and .mts files, including support for tsconfig.json baseUrl and recursive extends.The Resolver is responsible for mapping a module specifier (e.g., "react" or "./utils") to a physical location. To maximize performance, Bun uses thread-local path buffers to avoid frequent heap allocations during the resolution walk. src/resolver/resolver.zig49-88
The algorithm follows Node.js resolution with extensions for TypeScript and JSX. It handles relative paths, absolute paths, and package-based lookups in node_modules.
Sources: src/resolver/resolver.zig6-27 src/resolver/package_json.zig142-176
Bun processes package.json files to determine module boundaries and resolution redirects. The PackageJSON struct stores parsed metadata, including exports, imports, and browser maps. src/resolver/package_json.zig21-102
| Field | Code Entity | Description |
|---|---|---|
exports | exports: ?ExportsMap | Defines entry points and conditional exports (e.g., import vs require). src/resolver/package_json.zig100 |
imports | imports: ?ExportsMap | Internal aliases for the package, often used for environment-specific shims. src/resolver/package_json.zig101 |
browser | browser_map: BrowserMap | Redirects module paths for browser-compatible versions. src/resolver/package_json.zig98 |
sideEffects | side_effects: SideEffects | Informs the bundler if modules can be safely tree-shaken. Supports booleans, file lists, and globs. src/resolver/package_json.zig115-141 |
Sources: src/resolver/package_json.zig73-98 src/resolver/package_json.zig142-176
Bun natively understands tsconfig.json. The resolver handles complex features like paths mapping, baseUrl, and recursive extends chains.
When a module specifier matches a pattern in compilerOptions.paths, Bun iterates through the array of fallback paths. It supports the ${configDir} template variable for portable configurations.
TSConfig Code Integration
Sources: src/resolver/resolver.zig51-54 src/resolver/resolver.zig66-71
Bun implements Node.js internals like _nodeModulePaths and createRequire to ensure compatibility with existing ecosystems.
_nodeModulePaths(from): Generates the array of node_modules directories to search by walking up the directory tree. test/js/node/module/node-module-module.test.js68-89Module._extensions: Supports .js, .json, and .node (native) extensions. Bun also includes .ts, .tsx, and .mts in its internal resolution logic. test/js/node/module/node-module-module.test.js180-182.node files are loaded via Bun's N-API implementation, allowing binary modules to function seamlessly. test/js/node/module/node-module-module.test.js180-182Bun maintains a unified registry for all modules. This allows for high-performance interop where an ES Module can import a CommonJS module, and a CommonJS module can require() an ES Module (if it does not contain top-level await).
The module system is closely tied to the package manager's lockfile (bun.lockb). The Lockfile struct stores PackageID and DependencyID mappings to ensure consistent resolution across different environments. src/install/lockfile.zig10-15
| Component | Code Entity | Role |
|---|---|---|
| Dependency | Dependency struct | Represents a requirement (name + version range) from package.json. src/install/dependency.zig25-37 |
| PackageID | PackageID (u32) | A unique identifier for a resolved package in the lockfile. src/install/install.zig95 |
| Resolution | Resolution struct | Maps a DependencyID to a specific PackageID. src/install/lockfile.zig103 |
Sources: src/install/install.zig95-108 src/install/lockfile.zig1-30
Refresh this wiki
This wiki was recently refreshed. Please wait 7 days to refresh again.