Built-in loaders supported by Bun bundler
The Bun bundler has built-in loaders for the following file types: .js, .cjs, .mjs, .mts, .cts, .ts, .tsx, .jsx, .css, .json, .jsonc, .toml, .yaml, .yml, .txt, .wasm, .node, .html, and .sh. The bundler and runtime both support the same set of file types by default.
Loader names and extension mapping
Bun uses file extensions to choose which built-in loader parses a file. Every loader has a name (such as js, tsx, or json). Plugins that extend Bun with custom loaders refer to these names.
Explicit loader specification with import attributes
To specify a loader explicitly, use the 'type' import attribute. Example: import my_toml from './my_file' with { type: 'toml' }; or with dynamic imports: const { default: my_toml } = await import('./my_file', { with: { type: 'toml' } });
js loader behavior
The js loader is the default for .cjs and .mjs files. It parses the code and applies a set of default transforms like dead-code elimination and tree shaking. Bun does not down-convert syntax.
jsx loader behavior
The jsx loader is the default for .js and .jsx files. It is the same as the js loader but JSX syntax is supported. By default, JSX is down-converted to plain JavaScript; the exact output depends on the jsx* compiler options in your tsconfig.json.
ts loader behavior
The ts loader is the default for .ts, .mts, and .cts files. It strips out all TypeScript syntax, then behaves identically to the js loader. Bun does not perform typechecking.
tsx loader behavior
The tsx loader is the default for .tsx files. It transpiles both TypeScript and JSX to vanilla JavaScript.
json loader behavior
The json loader is the default for .json files. JSON files can be directly imported. During bundling, the parsed JSON is inlined into the bundle as a JavaScript object. If a .json file is passed as an entrypoint to the bundler, it is converted to a .js module that export defaults the parsed object.
jsonc loader behavior
The jsonc loader is the default for .jsonc files. JSONC (JSON with Comments) files can be directly imported. Bun parses them, stripping out comments and trailing commas. During bundling, the parsed JSONC is inlined into the bundle as a JavaScript object, identical to the json loader. Bun automatically uses the jsonc loader for tsconfig.json, jsconfig.json, package.json, and bun.lock files.
toml loader behavior
The toml loader is the default for .toml files. TOML files can be directly imported. Bun parses them with its native TOML parser. During bundling, the parsed TOML is inlined into the bundle as a JavaScript object. If a .toml file is passed as an entrypoint, it is converted to a .js module that export defaults the parsed object.
yaml loader behavior
The yaml loader is the default for .yaml and .yml files. YAML files can be directly imported. Bun parses them with its native YAML parser. During bundling, the parsed YAML is inlined into the bundle as a JavaScript object. If a .yaml or .yml file is passed as an entrypoint, it is converted to a .js module that export defaults the parsed object.
xml loader behavior
The xml loader is the default for .xml files. 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: one key for the root element, '@name' keys for attributes, arrays for repeated child elements, '#text' for text next to attributes or children, and every value a string. During bundling, the parsed XML is inlined into the bundle as a JavaScript object. If a .xml file is passed as an entrypoint, it is converted to a .js module that export defaults the parsed object.
text loader behavior
The text loader is the default for .txt files. Text files can be directly imported. The file is read and returned as a string. When referenced during a build, the contents are inlined into the bundle as a string. If a .txt file is passed as an entrypoint, it is converted to a .js module that export defaults the file contents.
napi loader behavior
The napi loader is the default for .node files. In the runtime, native addons can be directly imported. In the bundler, .node files are handled with the file loader.
sqlite loader behavior and requirements
The sqlite loader requires the with { 'type': 'sqlite' } import attribute. In the runtime and bundler, SQLite databases can be directly imported. Bun loads the database with bun:sqlite. The sqlite loader is only supported when the target is bun. By default, the database file on disk is not bundled into the final output; it stays external to the bundle. You can embed the database into the bundle with the 'embed' attribute: import db from './my.db' with { type: 'sqlite', embed: 'true' };. When using a standalone executable, the database is embedded into the single-file executable. Otherwise, the database to embed is copied into the outdir with a hashed filename.
html loader behavior
The html loader is the default for .html files. 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='...'>), and preserves external URLs (by default, anything starting with http:// or https://). The loader uses lol-html to extract script and link tags as entrypoints, and other assets as external.
html loader supported selectors
The html loader supports the following CSS selectors for extracting and bundling: 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], and video[src].
html loader context-dependent behavior
The html loader behaves differently depending on how it's used. In a static build (bun build ./index.html), Bun produces a static site with all assets bundled and hashed. In the runtime (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. In a full-stack build (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 serve pre-bundled assets in production.
css loader behavior
The css loader is the default for .css files. CSS files can be directly imported. The bundler parses and bundles them, handling @import statements and url() references. During bundling, all imported CSS files are bundled together into a single .css file in the output directory.
sh loader behavior
The sh loader is the default for .sh files. This loader parses Bun Shell scripts. It's only supported when starting Bun itself, so it's not available in the bundler or in the runtime.
file loader behavior
The file loader is the 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. In the runtime, Bun checks that the file exists and resolves the import to its absolute path on disk. In the bundler, the file is copied into outdir as-is, and the import resolves to a relative path pointing to the copied file. If publicPath is set, the import uses its value as a prefix to construct an absolute path/URL. The location and file name of the copied file are determined by the value of naming.asset.
file loader publicPath behavior
When using the file loader with the publicPath option: an empty string (default) resolves to './logo.svg', '/assets/' resolves to '/assets/logo.svg', and 'https://cdn.example.com/' resolves to 'https://cdn.example.com/logo.svg'.
Loader types available to plugins
Plugin loaders determine how content is processed. Available loader types are: js, jsx, ts, tsx, json, jsonc, toml, yaml, file, napi, wasm, text, css, and html.