Module Systems
Bun supports both ES Modules (ESM) and CommonJS (CJS):ES Modules
ES Modules
- Static imports and exports
- Top-level
awaitsupport - Tree-shaking friendly
- Strict mode by default
CommonJS
CommonJS
- Dynamic
require()calls - Synchronous loading
- Circular dependency handling
exportsshorthand
Interoperability
Bun seamlessly bridges ESM and CommonJS:ESM → CommonJS
CommonJS → ESM
src/runtime.zig:167 - CommonJS named exports feature
Resolution Algorithm
Bun’s module resolution follows the Node.js algorithm with enhancements:Resolution Steps
- Built-in modules - Check for
node:*andbun:*modules - Relative/absolute paths - Resolve file paths
- Package imports - Search
node_modules - Extensions - Try
.ts,.tsx,.js,.jsx,.mjs,.cjs - Index files - Check
index.*files - package.json - Resolve via
exports,main,module
Relative Imports
Relative imports
Absolute Imports
Absolute imports
Package Imports
Package imports
Extension Resolution
Bun tries extensions in this order:- Exact match (if extension provided)
.ts.tsx.js.jsx.mjs.cjs.json
Extension resolution
package.json Fields
Bun respects multiple package.json fields:exports Field
Modern package entry points:package.json
Conditional Exports
Conditional exports
bunnodeimport/requiredefault
src/options.zig:508-533 - Default conditions per target
main, module, browser
Legacy entry point fields:Legacy fields
exports(if present)modulemainindex.js
src/options.zig:455-505 - Main field resolution
type Field
Determines module system:package.json
package.json
.mjsalways ESM.cjsalways CommonJS
Path Mapping (tsconfig.json)
Configure import aliases:tsconfig.json
Using path aliases
src/resolver/resolver.zig - Path resolution
Built-in Modules
Bun provides built-in modules:Node.js Compatibility
Node.js modules
node: prefix.
Implementation: src/options.zig:150-333 - Node.js built-in patterns
Bun-specific Modules
Bun modules
bun- Main Bun APIsbun:ffi- Foreign Function Interfacebun:sqlite- SQLite databasebun:test- Test runnerbun:jsc- JavaScriptCore internalsbun:wrap- Internal runtime
Import Attributes
Specify how to import modules:Import attributes
json- Parse as JSONtext- Load as stringfile- Copy to outputtoml- Parse as TOML
Dynamic Imports
Load modules at runtime:Dynamic imports
- Code splitting
- Lazy loading
- Conditional imports
- String-based paths
Circular Dependencies
Bun handles circular dependencies:Circular dependencies
Import Maps
Map bare specifiers to URLs:import-map.json
Using import maps
Import maps are experimental and primarily for browser compatibility.
Resolution Cache
Bun caches module resolution results: Cache location:- Resolution cache: In-memory
- Transpiler cache: Disk (see TypeScript)
- File system changes (watch mode)
- package.json modifications
- node_modules updates
Module Loader Hooks
Customize module loading (advanced):Module hooks
Preloading
Load modules before main script:Preload flag
bunfig.toml
- Environment setup
- Polyfills
- Global initialization
- Instrumentation
Performance
Optimization Tips
-
Use explicit extensions
-
Prefer ESM over CommonJS
- Static analysis
- Tree-shaking
- Async loading
-
Use barrel files sparingly
-
Leverage dynamic imports for code splitting
Debugging
Trace Resolution
Debug resolution
Print Resolved Paths
Print resolution
Resolution Failures
Common errors
Implementation Details
Module resolution implementation:- Resolver:
src/resolver/resolver.zig- Core resolution logic - Module loader:
src/bun.js/module_loader/- Module loading - Import record:
src/import_record.zig- Import tracking - Package.json:
src/resolver/package_json.zig- Package metadata
Related
- Loaders - File type handling
- TypeScript - Path mapping configuration
- bunfig.toml - Module configuration
- Package Manager - Installing dependencies