Bun

Loaders

The Bun bundler implements a set of default loaders out of the box. As a rule of thumb, the bundler and the runtime both support the same set of file types out of the box.

.js .cjs .mjs .mts .cts .ts .tsx .jsx .toml .json .txt .wasm .node

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

Built-in loaders

js

JavaScript. Default for .cjs and .mjs.

Parses the code and applies a set of default transforms, like dead-code elimination, tree shaking, and environment variable inlining. Note that Bun does not attempt to down-convert syntax at the moment.

jsx

JavaScript + JSX.. Default for .js and .jsx.

Same as the js loader, but JSX syntax is supported. By default, JSX is down-converted to plain JavaScript; the details of how this is done depends on the jsx* compiler options in your tsconfig.json. Refer to the TypeScript documentation on JSX for more information.

ts

TypeScript loader. Default for .ts, .mts, and .cts.

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

tsx

TypeScript + JSX loader. Default for .tsx. Transpiles both TypeScript and JSX to vanilla JavaScript.

json

JSON loader. Default for .json.

JSON files can be directly imported.

import pkg from "./package.json";
pkg.name; // => "my-package"

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

var 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 defaults the parsed object.

Input
Output
Input
{
  "name": "John Doe",
  "age": 35,
  "email": "johndoe@example.com"
}
Output
export default {
  name: "John Doe",
  age: 35,
  email: "johndoe@example.com"
}

toml

TOML loader. Default for .toml.

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

import config from "./bunfig.toml";
config.logLevel; // => "debug"

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

var config = {
  logLevel: "debug",
  // ...other fields
};
config.logLevel;

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

Input
Output
Input
name = "John Doe"
age = 35
email = "johndoe@example.com"
Output
export default {
  name: "John Doe",
  age: 35,
  email: "johndoe@example.com"
}

text

Text loader. Default for .txt.

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

import contents from "./file.txt";
console.log(contents); // => "Hello, world!"

When referenced during a build, the contents are into the bundle as a string.

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 defaults the file contents.

Input
Output
Input
Hello, world!
Output
export default "Hello, world!";

wasm

WebAssembly loader. Default for .wasm.

In the runtime, WebAssembly files can be directly imported. The file is read and returned as a WebAssembly.Module.

import wasm from "./module.wasm";
console.log(wasm); // => WebAssembly.Module

In the bundler, .wasm files are handled using the file loader.

napi

Native addon loader. Default for .node.

In the runtime, native addons can be directly imported.

import addon from "./addon.node";
console.log(addon);

In the bundler, .node files are handled using the file loader.

file

File loader. Default for all unrecognized file types.

The file loader resolves the import as a path/URL to the imported file. It's commonly used for referencing media or font assets.

logo.ts
import logo from "./logo.svg";
console.log(logo);

In the runtime, Bun checks that the logo.svg file exists and converts it to an absolute path to the location of logo.svg on disk.

bun run logo.ts
/path/to/project/logo.svg

In the bundler, things are slightly different. The file is copied into outdir as-is, and the import is resolved as a relative path pointing to the copied file.

Output
var logo = "./logo.svg";
console.log(logo);

If a value is specified for publicPath, the import will use value as a prefix to construct an absolute path/URL.

Public pathResolved import
"" (default)/logo.svg
"/assets"/assets/logo.svg
"https://cdn.example.com/"https://cdn.example.com/logo.svg

The location and file name of the copied file is determined by the value of naming.asset.

This loader is copied into the outdir as-is. The name of the copied file is determined using the value of naming.asset.

Fixing TypeScript import errors