> ## 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.

# Module Resolution

> How Bun resolves ES modules, CommonJS modules, path aliases, and package exports.

Bun supports both ES modules (`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:

<CodeGroup>
  ```typescript index.ts theme={null}
  import { hello } from "./hello";

  hello();
  ```

  ```typescript hello.ts theme={null}
  export function hello() {
    console.log("Hello world!");
  }
  ```
</CodeGroup>

Running `index.ts` prints "Hello world!":

```bash theme={null}
bun index.ts
```

```
Hello world!
```

The import path `./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`

If an extension is present, Bun only looks for a file with that exact extension.

### 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](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-7.html#new-file-extensions):

```typescript theme={null}
import { hello } from "./hello.js"; // resolves hello.ts if hello.js is absent
```

## 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:

```typescript theme={null}
const { foo } = require("./foo");
const { bar } = require("./bar.mjs");
const { baz } = require("./baz.tsx");
```

When you `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:

```typescript theme={null}
import { foo } from "./foo";
import bar from "./bar.ts";
import { stuff } from "./my-commonjs.cjs";
```

### Mixing `import` and `require()`

In Bun, you can use both in the same file:

```typescript theme={null}
import { stuff } from "./my-commonjs.cjs";
import Stuff from "./my-commonjs.cjs";

const myStuff = require("./my-commonjs.cjs");
```

<Note>
  You cannot `require()` a file that uses top-level `await`, since `require()` is synchronous. Use `import` or dynamic `import()` in that case.
</Note>

## Importing packages

Bun implements the Node.js module resolution algorithm. Import packages from `node_modules` using bare specifiers:

```typescript theme={null}
import { stuff } from "foo";
```

Bun scans up the file system for a `node_modules` directory containing the package `foo`.

### `NODE_PATH`

Bun supports `NODE_PATH` for additional module search directories:

```bash theme={null}
NODE_PATH=./packages bun run src/index.js
```

Multiple paths are separated by `:` on Unix/macOS and `;` on Windows:

```bash theme={null}
NODE_PATH=./packages:./lib bun run src/index.js
```

### 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:

```json theme={null}
{
  "name": "foo",
  "exports": {
    "bun": "./index.ts",
    "node": "./index.js",
    "require": "./index.js",
    "import": "./index.mjs",
    "default": "./index.js"
  }
}
```

<Tip>
  The `"bun"` export condition lets you ship TypeScript source directly to npm. If you specify a `*.ts` entrypoint in the `"bun"` condition, Bun will import and execute your TypeScript files without transpilation.
</Tip>

Bun respects subpath [exports](https://nodejs.org/api/packages.html#subpath-exports) and [imports](https://nodejs.org/api/packages.html#imports):

```json theme={null}
{
  "name": "foo",
  "exports": {
    ".": {
      "import": "./index.mjs",
      "require": "./index.js"
    }
  }
}
```

Specifying any subpath in `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"`:

```json theme={null}
{
  "name": "foo",
  "module": "./index.js",
  "main": "./index.js"
}
```

### Custom export conditions

Use `--conditions` to specify custom conditions when resolving `exports`:

```bash theme={null}
bun --conditions="react-server" ./app/foo/route.js
```

## Path re-mapping

### `tsconfig.json` paths

Bun supports import path aliases via TypeScript's [`compilerOptions.paths`](https://www.typescriptlang.org/tsconfig#paths):

```json theme={null}
{
  "compilerOptions": {
    "paths": {
      "config": ["./config.ts"],
      "components/*": ["components/*"]
    }
  }
}
```

Non-TypeScript projects can use a `jsconfig.json` with the same structure.

### `package.json` imports field

Bun supports [Node.js-style subpath imports](https://nodejs.org/api/packages.html#subpath-imports) via the `"imports"` field in `package.json`. These paths must start with `#`:

```json theme={null}
{
  "imports": {
    "#config": "./config.ts",
    "#components/*": "./components/*"
  }
}
```

Both `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:

```typescript theme={null}
import.meta.dir;     // "/path/to/project"
import.meta.file;    // "file.ts"
import.meta.path;    // "/path/to/project/file.ts"
import.meta.url;     // "file:///path/to/project/file.ts"
import.meta.main;    // true if this file is the entry point
import.meta.resolve("zod"); // "file:///path/to/project/node_modules/zod/index.js"
```

| 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.                                                     |
