549 lines
13 KiB
Plaintext
549 lines
13 KiB
Plaintext
---
|
|
title: "File Types"
|
|
description: "File types and loaders supported by Bun's bundler and runtime"
|
|
---
|
|
|
|
The Bun bundler implements a set of default loaders. As a rule of thumb, the bundler and the runtime support the same set of file types.
|
|
|
|
`.js` `.cjs` `.mjs` `.mts` `.cts` `.ts` `.tsx` `.jsx` `.css` `.json` `.jsonc` `.json5` `.toml` `.yaml` `.yml` `.xml` `.txt` `.text` `.md` `.markdown` `.wasm` `.node` `.html` `.sh`
|
|
|
|
Bun uses the file extension to pick the built-in _loader_ that parses the file. Every loader has a name, such as `js`, `tsx`, or `json`. These names are used when building [plugins](/bundler/plugins) that extend Bun with custom loaders.
|
|
|
|
To specify a loader explicitly, use the `type` import attribute.
|
|
|
|
```ts
|
|
import my_toml from "./my_file" with { type: "toml" };
|
|
// or with dynamic imports
|
|
const { default: my_toml } = await import("./my_file", { with: { type: "toml" } });
|
|
```
|
|
|
|
---
|
|
|
|
## Built-in loaders
|
|
|
|
### `js`
|
|
|
|
**JavaScript**. Default for `.cjs` and `.mjs`.
|
|
|
|
Parses the code and applies a set of default transforms like dead-code elimination and tree shaking. Bun does not down-convert syntax.
|
|
|
|
### `jsx`
|
|
|
|
**JavaScript + JSX**. Default for `.js` and `.jsx`.
|
|
|
|
Same as the `js` loader, but JSX syntax is supported. By default, Bun down-converts JSX to plain JavaScript; the details depend on the `jsx*` compiler options in your `tsconfig.json`. Refer to the TypeScript documentation [on JSX](https://www.typescriptlang.org/docs/handbook/jsx.html).
|
|
|
|
### `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.
|
|
|
|
```ts
|
|
import pkg from "./package.json";
|
|
pkg.name; // => "my-package"
|
|
```
|
|
|
|
During bundling, Bun inlines the parsed JSON into the bundle as a JavaScript object.
|
|
|
|
```ts
|
|
var pkg = {
|
|
name: "my-package",
|
|
// ... other fields
|
|
};
|
|
pkg.name;
|
|
```
|
|
|
|
If you pass a `.json` file as an entrypoint to the bundler, Bun converts it to a `.js` module that `export default`s the parsed object.
|
|
|
|
<CodeGroup>
|
|
|
|
```json Input
|
|
{
|
|
"name": "John Doe",
|
|
"age": 35,
|
|
"email": "[email protected]"
|
|
}
|
|
```
|
|
|
|
```ts Output
|
|
export default {
|
|
name: "John Doe",
|
|
age: 35,
|
|
email: "[email protected]",
|
|
};
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
### `jsonc`
|
|
|
|
**JSON with Comments loader**. Default for `.jsonc`.
|
|
|
|
JSONC (JSON with Comments) files can be directly imported. Bun parses them, stripping out comments and trailing commas.
|
|
|
|
```ts
|
|
import config from "./config.jsonc";
|
|
console.log(config);
|
|
```
|
|
|
|
During bundling, Bun inlines the parsed JSONC into the bundle as a JavaScript object, identical to the `json` loader.
|
|
|
|
```ts
|
|
var config = {
|
|
option: "value",
|
|
};
|
|
```
|
|
|
|
<Note>
|
|
Bun automatically uses the `jsonc` loader for `tsconfig.json`, `jsconfig.json`, `package.json`, and `bun.lock` files.
|
|
</Note>
|
|
|
|
### `toml`
|
|
|
|
**TOML loader**. Default for `.toml`.
|
|
|
|
TOML files can be directly imported. Bun parses them with its fast native TOML parser.
|
|
|
|
```ts
|
|
import config from "./bunfig.toml";
|
|
config.logLevel; // => "debug"
|
|
|
|
// via import attribute:
|
|
// import myCustomTOML from './my.config' with {type: "toml"};
|
|
```
|
|
|
|
During bundling, Bun inlines the parsed TOML into the bundle as a JavaScript object.
|
|
|
|
```ts
|
|
var config = {
|
|
logLevel: "debug",
|
|
// ...other fields
|
|
};
|
|
config.logLevel;
|
|
```
|
|
|
|
If you pass a `.toml` file as an entrypoint, Bun converts it to a `.js` module that `export default`s the parsed object.
|
|
|
|
<CodeGroup>
|
|
|
|
```toml Input
|
|
name = "John Doe"
|
|
age = 35
|
|
email = "[email protected]"
|
|
```
|
|
|
|
```ts Output
|
|
export default {
|
|
name: "John Doe",
|
|
age: 35,
|
|
email: "[email protected]",
|
|
};
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
### `yaml`
|
|
|
|
**YAML loader**. Default for `.yaml` and `.yml`.
|
|
|
|
YAML files can be directly imported. Bun parses them with its fast native YAML parser.
|
|
|
|
```ts
|
|
import config from "./config.yaml";
|
|
console.log(config);
|
|
|
|
// via import attribute:
|
|
import data from "./data.txt" with { type: "yaml" };
|
|
```
|
|
|
|
During bundling, Bun inlines the parsed YAML into the bundle as a JavaScript object.
|
|
|
|
```ts
|
|
var config = {
|
|
name: "my-app",
|
|
version: "1.0.0",
|
|
// ...other fields
|
|
};
|
|
```
|
|
|
|
If you pass a `.yaml` or `.yml` file as an entrypoint, Bun converts it to a `.js` module that `export default`s the parsed object.
|
|
|
|
<CodeGroup>
|
|
|
|
```yaml Input
|
|
name: John Doe
|
|
age: 35
|
|
email: [email protected]
|
|
```
|
|
|
|
```ts Output
|
|
export default {
|
|
name: "John Doe",
|
|
age: 35,
|
|
email: "[email protected]",
|
|
};
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
### `json5`
|
|
|
|
**JSON5 loader**. Default for `.json5`.
|
|
|
|
JSON5 files can be directly imported. Bun parses them with its fast native JSON5 parser. JSON5 is a superset of JSON that adds comments, trailing commas, unquoted keys, single-quoted strings, and more.
|
|
|
|
```ts
|
|
import config from "./config.json5";
|
|
console.log(config);
|
|
|
|
// via import attribute:
|
|
import data from "./data.txt" with { type: "json5" };
|
|
```
|
|
|
|
During bundling, Bun inlines the parsed JSON5 into the bundle as a JavaScript object.
|
|
|
|
```ts
|
|
var config = {
|
|
name: "my-app",
|
|
version: "1.0.0",
|
|
// ...other fields
|
|
};
|
|
```
|
|
|
|
If you pass a `.json5` file as an entrypoint, Bun converts it to a `.js` module that `export default`s the parsed object.
|
|
|
|
<CodeGroup>
|
|
|
|
```json5 Input
|
|
{
|
|
// Configuration
|
|
name: "John Doe",
|
|
age: 35,
|
|
email: "[email protected]",
|
|
}
|
|
```
|
|
|
|
```ts Output
|
|
export default {
|
|
name: "John Doe",
|
|
age: 35,
|
|
email: "[email protected]",
|
|
};
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
### `xml`
|
|
|
|
**XML loader**. Default for `.xml`.
|
|
|
|
XML files can be directly imported. Bun parses them with its native XML 1.0 parser into the compact object shape of [`Bun.XML.parse`](/runtime/xml):
|
|
|
|
- One key for the root element
|
|
- `"@name"` keys for attributes
|
|
- Arrays for repeated child elements
|
|
- `"#text"` for text next to attributes or children
|
|
- Every value is a string
|
|
|
|
```ts
|
|
import doc from "./config.xml";
|
|
console.log(doc.config["@version"]);
|
|
|
|
// via import attribute:
|
|
import feed from "./export.rss" with { type: "xml" };
|
|
```
|
|
|
|
During bundling, Bun inlines the parsed XML into the bundle as a JavaScript object.
|
|
|
|
```ts
|
|
var doc = {
|
|
config: {
|
|
"@version": "2",
|
|
// ...other fields
|
|
},
|
|
};
|
|
```
|
|
|
|
If you pass a `.xml` file as an entrypoint, Bun converts it to a `.js` module that `export default`s the parsed object.
|
|
|
|
<CodeGroup>
|
|
|
|
```xml Input
|
|
<user id="1">
|
|
<name>John Doe</name>
|
|
<email>[email protected]</email>
|
|
<role>admin</role>
|
|
<role>editor</role>
|
|
</user>
|
|
```
|
|
|
|
```ts Output
|
|
export default {
|
|
user: {
|
|
"@id": "1",
|
|
name: "John Doe",
|
|
email: "[email protected]",
|
|
role: ["admin", "editor"],
|
|
},
|
|
};
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
### `text`
|
|
|
|
**Text loader**. Default for `.txt` and `.text`.
|
|
|
|
Text files can be directly imported. Bun reads the file and returns it as a string.
|
|
|
|
```ts
|
|
import contents from "./file.txt";
|
|
console.log(contents); // => "Hello, world!"
|
|
|
|
// To import an html file as text
|
|
// The "type' attribute can be used to override the default loader.
|
|
import html from "./index.html" with { type: "text" };
|
|
```
|
|
|
|
When the file is referenced during a build, Bun inlines the contents into the bundle as a string.
|
|
|
|
```ts
|
|
var contents = `Hello, world!`;
|
|
console.log(contents);
|
|
```
|
|
|
|
If you pass a `.txt` file as an entrypoint, Bun converts it to a `.js` module that `export default`s the file contents.
|
|
|
|
<CodeGroup>
|
|
|
|
```txt Input
|
|
Hello, world!
|
|
```
|
|
|
|
```ts Output
|
|
export default "Hello, world!";
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
### `md`
|
|
|
|
**Markdown loader**. Default for `.md` and `.markdown`.
|
|
|
|
Markdown files can be directly imported. Bun renders the file to HTML and returns the HTML as a string.
|
|
|
|
```ts
|
|
import html from "./README.md";
|
|
console.log(html); // => "<h1>Title</h1>\n"
|
|
|
|
// via import attribute (`markdown` is an alias of `md`):
|
|
import notes from "./notes.txt" with { type: "md" };
|
|
```
|
|
|
|
During bundling, Bun inlines the rendered HTML into the bundle as a string.
|
|
|
|
### `napi`
|
|
|
|
**Native addon loader**. Default for `.node`.
|
|
|
|
In the runtime, native addons can be directly imported.
|
|
|
|
```ts
|
|
import addon from "./addon.node";
|
|
console.log(addon);
|
|
```
|
|
|
|
In the bundler, Bun handles `.node` files using the [`file`](#file) loader.
|
|
|
|
### `sqlite`
|
|
|
|
**SQLite loader**. `with { "type": "sqlite" }` import attribute
|
|
|
|
In the runtime and bundler, SQLite databases can be directly imported. Bun loads the database with [`bun:sqlite`](/runtime/sqlite).
|
|
|
|
```ts
|
|
import db from "./my.db" with { type: "sqlite" };
|
|
```
|
|
|
|
The `sqlite` loader is only supported when the `target` is `bun`.
|
|
|
|
By default, the database is external to the bundle: Bun doesn't bundle the on-disk database file into the final output, so you can use a database loaded elsewhere.
|
|
|
|
You can change this behavior with the `"embed"` attribute:
|
|
|
|
```ts
|
|
// embed the database into the bundle
|
|
import db from "./my.db" with { type: "sqlite", embed: "true" };
|
|
```
|
|
|
|
With a [standalone executable](/bundler/executables), Bun embeds the database into the single-file executable.
|
|
|
|
Otherwise, the database to embed is copied into the `outdir` with a hashed filename.
|
|
|
|
### `html`
|
|
|
|
The `html` loader processes HTML files and bundles any referenced assets. It:
|
|
|
|
- Bundles and hashes referenced JavaScript files (`<script src="...">`)
|
|
- Bundles and hashes referenced CSS files (`<link rel="stylesheet" href="...">`)
|
|
- Hashes referenced images (`<img src="...">`)
|
|
- Preserves external URLs (by default, anything starting with `http://` or `https://`)
|
|
|
|
For example, given this HTML file:
|
|
|
|
<CodeGroup>
|
|
|
|
```html src/index.html
|
|
<!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>
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
Bun outputs a new HTML file with the bundled assets:
|
|
|
|
<CodeGroup>
|
|
|
|
```html dist/output.html
|
|
<!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>
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
The loader uses [`lol-html`](https://github.com/cloudflare/lol-html) to extract script and link tags as entrypoints, and other assets as external.
|
|
|
|
The list of selectors is:
|
|
|
|
- `audio[src]`
|
|
- `img[src]`
|
|
- `img[srcset]`
|
|
- `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]`
|
|
|
|
<Note>
|
|
|
|
**HTML Loader Behavior in Different Contexts**
|
|
|
|
The `html` loader behaves differently depending on how it's used:
|
|
|
|
1. **Static Build:** When you run `bun build ./index.html`, Bun produces a static site with all assets bundled and hashed.
|
|
|
|
2. **Runtime:** When you run `bun run server.ts` (where `server.ts` imports an HTML file), Bun bundles assets on-the-fly during development, enabling features like hot module replacement.
|
|
|
|
3. **Full-stack Build:** When you run `bun build --target=bun server.ts` (where `server.ts` imports an HTML file), the import resolves to a manifest object that `Bun.serve` uses to efficiently serve pre-bundled assets in production.
|
|
|
|
</Note>
|
|
|
|
### `css`
|
|
|
|
**CSS loader**. Default for `.css`.
|
|
|
|
CSS files can be directly imported. This is primarily useful when [bundling HTML](/bundler/html-static#importing-css-in-javascript), where CSS is bundled alongside HTML.
|
|
|
|
```ts
|
|
import "./styles.css";
|
|
```
|
|
|
|
The import returns no value; it's only used for its side effects.
|
|
|
|
### `sh` loader
|
|
|
|
**Bun Shell loader**. Default for `.sh` files
|
|
|
|
This loader parses [Bun Shell](/runtime/shell) scripts. It's only supported when starting Bun itself, so it's not available in the bundler or in the runtime.
|
|
|
|
```sh
|
|
bun run ./script.sh
|
|
```
|
|
|
|
### `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.
|
|
|
|
```ts logo.ts
|
|
import logo from "./logo.svg";
|
|
console.log(logo);
|
|
```
|
|
|
|
_In the runtime_, Bun checks that the `logo.svg` file exists and resolves the import to its absolute path on disk.
|
|
|
|
```bash
|
|
bun run logo.ts
|
|
/path/to/project/logo.svg
|
|
```
|
|
|
|
_In the bundler_, Bun copies the file into `outdir` as-is, and the import resolves to a relative path pointing to the copied file.
|
|
|
|
```ts Output
|
|
var logo = "./logo.svg";
|
|
console.log(logo);
|
|
```
|
|
|
|
If `publicPath` is set, the import uses its value as a prefix to construct an absolute path/URL.
|
|
|
|
| Public path | Resolved import |
|
|
| ---------------------------- | ---------------------------------- |
|
|
| `""` (default) | `./logo.svg` |
|
|
| `"/assets/"` | `/assets/logo.svg` |
|
|
| `"https://cdn.example.com/"` | `https://cdn.example.com/logo.svg` |
|
|
|
|
<Note>The value of [`naming.asset`](/bundler#naming) determines the location and file name of the copied file.</Note>
|
|
|
|
<Accordion title="Fixing TypeScript import errors">
|
|
If you're using TypeScript, you may get an error like this:
|
|
|
|
```ts
|
|
// TypeScript error
|
|
// Cannot find module './logo.svg' or its corresponding type declarations.
|
|
```
|
|
|
|
To fix this, create a `*.d.ts` file anywhere in your project (any name works) with the following contents:
|
|
|
|
```ts
|
|
declare module "*.svg" {
|
|
const content: string;
|
|
export default content;
|
|
}
|
|
```
|
|
|
|
This tells TypeScript to treat any default import from `.svg` as a string.
|
|
|
|
</Accordion>
|