Bun supports both ES modules (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/oven-sh/bun/llms.txt
Use this file to discover all available pages before exploring further.
import/export) and CommonJS (require/module.exports) simultaneously. You can use either syntax in any file, and they interoperate without configuration.
Syntax
Consider the following two files:index.ts prints “Hello world!”:
./hello has no extension. Extensions are optional but supported. Bun checks for the following files in order when resolving an extensionless path:
./hello.tsx./hello.jsx./hello.ts./hello.mjs./hello.js./hello.cjs./hello.json./hello/index.tsx./hello/index.jsx./hello/index.ts./hello/index.mjs./hello/index.js./hello/index.cjs./hello/index.json
TypeScript .js extension compatibility
If you import from "*.js" or "*.jsx", Bun additionally checks for a matching *.ts or *.tsx file. This is compatible with TypeScript’s ES module support:
Module systems
Bun has native support for both CommonJS and ES modules.Using require()
You can require() any file or package, including .ts and .mjs files:
require() an ES module, Bun returns the module namespace object (equivalent to import * as). When you require() a CommonJS module, it returns the module.exports object.
| Module type | require() | import * as |
|---|---|---|
| ES module | Module namespace | Module namespace |
| CommonJS | module.exports | default is module.exports; named keys are re-exported |
Using import
You can import from any file or package, including .cjs files:
Mixing import and require()
In Bun, you can use both in the same file:
You cannot
require() a file that uses top-level await, since require() is synchronous. Use import or dynamic import() in that case.Importing packages
Bun implements the Node.js module resolution algorithm. Import packages fromnode_modules using bare specifiers:
node_modules directory containing the package foo.
NODE_PATH
Bun supports NODE_PATH for additional module search directories:
: on Unix/macOS and ; on Windows:
Package exports field
When Bun finds a package, it reads its package.json to determine the entrypoint. It checks the exports field for the following conditions in order:
exports prevents other subpaths from being imported directly. Only explicitly exported paths are accessible.
If exports is not defined, Bun falls back to the "module" field (ESM only), then "main":
Custom export conditions
Use--conditions to specify custom conditions when resolving exports:
Path re-mapping
tsconfig.json paths
Bun supports import path aliases via TypeScript’s compilerOptions.paths:
jsconfig.json with the same structure.
package.json imports field
Bun supports Node.js-style subpath imports via the "imports" field in package.json. These paths must start with #:
tsconfig.json paths and package.json imports can be used together.
import.meta
The import.meta object gives a module access to information about itself. Bun implements the following properties:
| Property | Description |
|---|---|
import.meta.dir | Absolute path to the directory containing the current file. Equivalent to __dirname. |
import.meta.dirname | Alias for import.meta.dir (Node.js compatibility). |
import.meta.env | Alias for process.env. |
import.meta.file | The name of the current file, e.g. index.tsx. |
import.meta.path | Absolute path to the current file. Equivalent to __filename. |
import.meta.filename | Alias for import.meta.path (Node.js compatibility). |
import.meta.main | true if this file is the entry point to the current bun process, false otherwise. |
import.meta.resolve | Resolves a module specifier to a file:// URL. Equivalent to import.meta.resolve in browsers. |
import.meta.url | A file:// URL string for the current file. |