> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/zhcndoc/bun/llms.txt
> Use this file to discover all available pages before exploring further.

# Loaders

> Built-in loaders for the Bun bundler and runtime

The Bun bundler implements a set of default loaders out of the box.

> As a general rule: **The bundler and runtime both support the same set of file types.**

`.js` `.cjs` `.mjs` `.mts` `.cts` `.ts` `.tsx` `.jsx` `.css` `.json` `.jsonc` `.toml` `.yaml` `.yml` `.txt` `.wasm` `.node` `.html` `.sh`

Bun uses the file extension to determine which built-in loader should be used to parse the file. Each loader has a name, such as `js`, `tsx`, or `json`. These names are used when building custom loader plugins that extend Bun.

You can explicitly specify which loader to use using the `'type'` import attribute.

```ts theme={null}
import my_toml from "./my_file" with { type: "toml" };
// or with dynamic import
const { default: my_toml } = await import("./my_file", { with: { type: "toml" } });
```

## Built-in loaders

### `js`

**The JavaScript loader.** Used by default for `.cjs` and `.mjs` files.

Parses the code and applies a set of default transformations like dead code elimination and tree shaking. Note that Bun does not currently attempt to down-convert syntax.

***

### `jsx`

**The JavaScript + JSX loader.** Used by default for `.js` and `.jsx` files.

Identical to the `js` loader, but supports JSX syntax. By default, JSX is down-converted to vanilla JavaScript; the specifics of how JSX is transformed depends on the `jsx*` compiler options in your `tsconfig.json`. Refer to the [TypeScript docs on JSX](https://www.typescriptlang.org/tsconfig#jsx) for details.

***

### `ts`

**The TypeScript loader.** Used by default for `.ts`, `.mts`, and `.cts` files.

Strips all TypeScript syntax, then behaves identically to the `js` loader. Bun does not perform typechecking.

***

### `tsx`

**The TypeScript + JSX loader.** Used by default for `.tsx` files.

Transpiles TypeScript and JSX to vanilla JavaScript.

***

### `json`

**The JSON loader.** Used by default for `.json` files.

JSON files can be directly imported.

```js theme={null}
import pkg from "./package.json";
pkg.name; // => "my-package"
```

During bundling, the parsed JSON is inlined into the bundle as a JavaScript object.

```js theme={null}
const pkg = {
  name: "my-package",
  // ... other fields
};

pkg.name;
```

If a `.json` file is passed as an entrypoint to the bundler, it will be converted to a `.js` module that `export default`s the parsed object.

<CodeGroup>
  ```json Input theme={null}
  {
    "name": "John Doe",
    "age": 35,
    "email": "johndoe@example.com"
  }
  ```

  ```js Output theme={null}
  export default {
    name: "John Doe",
    age: 35,
    email: "johndoe@example.com",
  };
  ```
</CodeGroup>

***

### `jsonc`

**The JSON with comments (JSONC) loader.** Used by default for `.jsonc` files.

JSON with comments (JSONC) files can be directly imported. Bun will parse and strip out the comments and trailing commas.

```js theme={null}
import config from "./config.jsonc";
console.log(config);
```

During bundling, the parsed JSONC is inlined into the bundle as a JavaScript object, identical to the `json` loader.

```js theme={null}
var config = {
  option: "value",
};
```

<Note>
  Bun automatically uses the `jsonc` loader for `tsconfig.json`, `jsconfig.json`, `package.json`, and `bun.lock` files.
</Note>

***

### `toml`

**The TOML loader.** Used by default for `.toml` files.

TOML files can be directly imported. Bun will parse them using its fast native TOML parser.

```js theme={null}
import config from "./bunfig.toml";
config.logLevel; // => "debug"

// With import attributes:
// import myCustomTOML from './my.config' with {type: "toml"};
```

During bundling, the parsed TOML is inlined into the bundle as a JavaScript object.

```js theme={null}
var config = {
  logLevel: "debug",
  // ...other fields
};
config.logLevel;
```

If a `.toml` file is passed as an entrypoint to the bundler, it will be converted to a `.js` module that `export default`s the parsed object.

<CodeGroup>
  ```toml Input theme={null}
  name = "John Doe"
  age = 35
  email = "johndoe@example.com"
  ```

  ```js Output theme={null}
  export default {
    name: "John Doe",
    age: 35,
    email: "johndoe@example.com",
  };
  ```
</CodeGroup>

***

### `yaml`

**The YAML loader.** Used by default for `.yaml` and `.yml` files.

YAML files can be directly imported. Bun will parse them using its fast native YAML parser.

```js theme={null}
import config from "./config.yaml";
console.log(config);

// With import attributes:
import data from "./data.txt" with { type: "yaml" };
```

During bundling, the parsed YAML is inlined into the bundle as a JavaScript object.

```js theme={null}
var config = {
  name: "my-app",
  version: "1.0.0",
  // ...other fields
};
```

If a `.yaml` or `.yml` file is passed as an entrypoint to the bundler, it will be converted to a `.js` module that `export default`s the parsed object.

<CodeGroup>
  ```yaml Input theme={null}
  name: John Doe
  age: 35
  email: johndoe@example.com
  ```

  ```js Output theme={null}
  export default {
    name: "John Doe",
    age: 35,
    email: "johndoe@example.com",
  };
  ```
</CodeGroup>

***

### `text`

**The text loader.** Used by default for `.txt` files.

The contents of the text file are read and inlined into the bundle as a string. Text files can be directly imported. The file contents are read and returned as a string.

```js theme={null}
import contents from "./file.txt";
console.log(contents); // => "Hello, world!"

// Import HTML file as text
// You can override the default loader with the "type" attribute.
import html from "./index.html" with { type: "text" };
```

During bundling, the file contents are inlined into the bundle as a string.

```js theme={null}
var contents = `Hello, world!`;
console.log(contents);
```

If a `.txt` file is passed as an entrypoint, it will be converted to a `.js` module that `export default`s the file contents.

<CodeGroup>
  ```txt Input theme={null}
  Hello, world!
  ```

  ```js Output theme={null}
  export default "Hello, world!";
  ```
</CodeGroup>

***

### `napi`

**The native addon loader.** Used by default for `.node` files.

At runtime, native addons can be directly imported.

```js theme={null}
import addon from "./addon.node";
console.log(addon);
```

<Note>In the bundler, `.node` files are treated with the file loader.</Note>

***

### `sqlite`

**The SQLite loader.** Requires the `with { "type": "sqlite" }` import attribute.

SQLite database files can be directly imported in the runtime and bundler. The database will be loaded using `bun:sqlite`.

```js theme={null}
import db from "./my.db" with { type: "sqlite" };
```

<Warning>This feature is only supported when the target is `bun`.</Warning>

By default, the database file is external to the bundle (so you can load the database elsewhere), meaning the database file on disk is not bundled into the final output.

You can change this behavior with the `"embed"` attribute:

```js theme={null}
// Embed the database into the bundle
import db from "./my.db" with { type: "sqlite", embed: "true" };
```

<Info>
  When using standalone executables, the database is embedded into the standalone executable.

  Otherwise, embedded databases are copied to the output directory `outdir` with a hashed filename.
</Info>

***

### `html`

**The HTML loader.** Used by default for `.html` files.

The `html` loader processes HTML files and bundles all referenced assets. It will:

* Bundle and hash referenced JavaScript files (`<script src="...">`)
* Bundle and hash referenced CSS files (`<link rel="stylesheet" href="...">`)
* Hash referenced images (`<img src="...">`)
* Preserve external URLs (those starting with `http://` or `https://` by default)

For example, given this HTML file:

```html theme={null}
<!DOCTYPE html>
<html>
  <body>
    <img src="./image.jpg" alt="Local image" />
    <img src="https://example.com/image.jpg" alt="External image" />
    <script type="module" src="./script.js"></script>
  </body>
</html>
```

It will output a new HTML file that references the bundled assets:

```html theme={null}
<!DOCTYPE html>
<html>
  <body>
    <img src="./image-HASHED.jpg" alt="Local image" />
    <img src="https://example.com/image.jpg" alt="External image" />
    <script type="module" src="./output-ALSO-HASHED.js"></script>
  </body>
</html>
```

Under the hood, it uses [`lol-html`](https://github.com/cloudflare/lol-html) to extract script and link tags as entrypoints and other assets as external assets.

<Accordion title="List of supported HTML selectors">
  The following selectors are currently supported:

  * `audio[src]`
  * `iframe[src]`
  * `img[src]`
  * `img[srcset]`
  * `link:not([rel~='stylesheet']):not([rel~='modulepreload']):not([rel~='manifest']):not([rel~='icon']):not([rel~='apple-touch-icon'])[href]`
  * `link[as='font'][href], link[type^='font/'][href]`
  * `link[as='image'][href]`
  * `link[as='style'][href]`
  * `link[as='video'][href], link[as='audio'][href]`
  * `link[as='worker'][href]`
  * `link[rel='icon'][href], link[rel='apple-touch-icon'][href]`
  * `link[rel='manifest'][href]`
  * `link[rel='stylesheet'][href]`
  * `script[src]`
  * `source[src]`
  * `source[srcset]`
  * `video[poster]`
  * `video[src]`
</Accordion>

<Note>
  **HTML loader behavior in different scenarios**

  The behavior of the `html` loader depends on how it's used:

  * Static build: When running `bun build ./index.html`, Bun generates a static site with all assets bundled and hashed.
  * Runtime: When running `bun run server.ts` where `server.ts` imports an HTML file, Bun dynamically bundles assets during development with features like hot module replacement.
  * Full-stack build: When running `bun build --target=bun server.ts` where `server.ts` imports an HTML file, the import resolves to a manifest object for efficiently serving pre-bundled assets in production with `Bun.serve`.
</Note>

***

### `css`

**The CSS loader.** Used by default for `.css` files.

CSS files can be directly imported. The bundler will parse and bundle CSS files, supporting `@import` statements and `url()` references.

```js theme={null}
import "./styles.css";
```

During bundling, all imported CSS files are merged into a single `.css` file that is written to the output directory.

```css theme={null}
.my-class {
  background: url("./image.png");
}
```

See [Bundler > CSS](/bundler/css) for complete documentation.

***

### `sh`

**The Bun Shell loader.** Used by default for `.sh` files.

This loader is used to parse Bun Shell scripts. It's only supported when starting Bun itself, so it's not available in the bundler or runtime.

```bash theme={null}
bun run ./script.sh
```

***

### `file`

**The file loader.** Used by default for all unrecognized file types.

This loader resolves an import to a path or URL to the imported file. It's commonly used to reference media or font assets.

```js theme={null}
// logo.ts
import logo from "./logo.svg";
console.log(logo);
```

At runtime, Bun checks whether the `logo.svg` file exists and converts it to an absolute path to the file on disk.

```bash theme={null}
bun run logo.ts
# Output: /path/to/project/logo.svg
```

In the bundler, things work a little differently. The file is copied as-is into the output directory `outdir`, and the import resolves to a relative path pointing to the copied file.

```js theme={null}
// Output
var logo = "./logo.svg";
console.log(logo);
```

If a value is specified for `publicPath`, the import will be prefixed with that value, creating an absolute path or URL.

| Public path                  | Resolved import                    |
| ---------------------------- | ---------------------------------- |
| `""` (default)               | `/logo.svg`                        |
| `"/assets"`                  | `/assets/logo.svg`                 |
| `"https://cdn.example.com/"` | `https://cdn.example.com/logo.svg` |

<Note>
  The location and filename of the copied file is determined by the value of `naming.asset`.

  This loader copies the file as-is into `outdir`, with the copied filename determined by `naming.asset`.
</Note>

## Custom loaders

You can define custom loaders using the `loader` option in the bundler API:

```ts theme={null}
await Bun.build({
  entrypoints: ['./index.tsx'],
  outdir: './out',
  loader: {
    ".png": "dataurl",
    ".txt": "file",
  },
});
```

Or via plugins for more complex transformations. See [Bundler > Plugins](/bundler/plugins) for details.
