{% callout %}
**Note** — Available in the Bun v0.6.0 nightly. Run `bun upgrade --canary` to try it out.
{% /callout %}
Bun's fast native bundler is now in beta. It can be used via the `bun build` CLI command or the `Bun.build()` JavaScript API.
{% codetabs %}
```ts#JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './build',
});
```
```sh#CLI
$ bun build ./index.tsx --outdir ./build
```
{% /codetabs %}
## Why bundle?
The bundler is a key piece of infrastructure in the JavaScript ecosystem. As a brief overview of why bundling is so important:
- **Reducing HTTP requests.** A single package in `node_modules` may consist of hundreds of files, and large applications may have dozens of such dependencies. Loading each of these files with a separate HTTP request becomes untenable very quickly, so bundlers are used to convert our application source code into a smaller number of self-contained "bundles" that can be loaded with a single request.
- **Code transforms.** Modern apps are commonly built with languages or tools like TypeScript, JSX, and CSS modules, all of which must be converted into plain JavaScript and CSS before they can be consumed by a browser. The bundler is the natural place to configure these transformations.
- **Framework features.** Frameworks rely on bundler plugins & code transformations to implement common patterns like file-system routing, client-server code co-location (think `getServerSideProps` or Remix loaders), and server components.
Let's jump into the bundler API.
## Basic example
Let's build our first bundle. You have the following two files, which implement a simple client-side rendered React app.
{% codetabs %}
```tsx#./index.tsx
import * as ReactDOM from 'react-dom/client';
import {Component} from "./Component"
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
{props.message}
} ``` {% /codetabs %} Here, `index.tsx` is the "entrypoint" to our application. Commonly, this will be a script that performs some _side effect_, like starting a server or—in this case—initializing a React root. Because we're using TypeScript & JSX, we need to bundle our code before it can be sent to the browser. To create our bundle: {% codetabs %} ```ts#JavaScript await Bun.build({ entrypoints: ['./index.tsx'], outdir: './out', }) ``` ```bash#CLI $ bun build ./index.tsx --outdir ./out ``` {% /codetabs %} For each file specified in `entrypoints`, Bun will generate a new bundle. This bundle will be written to disk in the `./out` directory (as resolved from the current working directory). After running the build, the file system looks like this: ```ts . ├── index.tsx ├── Component.tsx └── out └── index.js ``` The contents of the `out/index.js` file looks something like this: ```js#out/index.js // ... // ~20k lines of code // including the contents of `react-dom/client` and all its dependencies // this is where the $jsxDEV and $createRoot functions are defined // Component.tsx function Component(props) { return $jsxDEV("p", { children: props.message }, undefined, false, undefined, this); } // index.tsx var rootNode = document.getElementById("root"); var root = $createRoot(rootNode); root.render($jsxDEV(Component, { message: "Sup!" }, undefined, false, undefined, this)); ``` {% details summary="Tutorial: Run this file in your browser" %} We can load this file in the browser to see our app in action. Create an `index.html` file in the `out` directory: ```bash $ touch out/index.html ``` Then paste the following contents into it: ```html ``` Then spin up a static file server serving the `out` directory: ```bash $ bunx serve out ``` Visit `http://localhost:5000` to see your bundled app in action. {% /details %} ## Content types Like the Bun runtime, the bundler supports an array of file types out of the box. The following table breaks down the bundler's set of standard "loaders". Refer to [Bundler > File types](/docs/runtime/loaders) for full documentation. {% table %} - Extensions - Details --- - `.js` `.cjs` `.mjs` `.mts` `.cts` `.ts` `.tsx` - Uses Bun's built-in transpiler to parse the file and transpile TypeScript/JSX syntax to vanilla JavaScript. The bundler executes a set of default transforms, including dead code elimination, tree shaking, and environment variable inlining. At the moment Bun does not attempt to down-convert syntax; if you use recently ECMAScript syntax, that will be reflected in the bundled code. --- - `.json` - JSON files are parsed and inlined into the bundle as a JavaScript object. ```ts import pkg from "./package.json"; pkg.name; // => "my-package" ``` --- - `.toml` - TOML files are parsed and inlined into the bundle as a JavaScript object. ```ts import config from "./bunfig.toml"; config.logLevel; // => "debug" ``` --- - `.txt` - The contents of the text file are read and inlined into the bundle as a string. ```ts import contents from "./file.txt"; console.log(contents); // => "Hello, world!" ``` {% /table %} ### Assets If the bundler encounters an import with an unrecognized extension, it treats the imported file as an _external file_. The referenced file is copied as-is into `outdir`, and the import is resolved as a _path_ to the file. {% codetabs %} ```ts#Build file await Bun.build({ entrypoints: ['./index.ts'], outdir: './out' }) ``` ```ts#Input import logo from "./logo.svg"; console.log(logo); ``` ```ts#Output var logo = "./logo-ab237dfe.svg"; console.log(logo); ``` {% /codetabs %} {% callout %} The exact behavior of the file loader is also impacted by [`naming`](#naming) and [`publicPath`](#publicpath). {% /callout %} Refer to the [Bundler > Loaders](/docs/bundler/loaders#file) page for more complete documentation on the file loader. ### Plugins The behavior described in this table can be overridden with [plugins](/docs/bundler/plugins). Refer to the [Bundler > Loaders](/docs/bundler/plugins) page for complete documentation. ## API ### `entrypoints` **Required.** An array of paths corresponding to the entrypoints of our application. One bundle will be generated for each entrypoint. {% codetabs %} ```ts#JavaScript const result = await Bun.build({ entrypoints: ['./index.ts'] }); // => Promise await result; // => { outputs: Array<{ path: string; result: Blob }> } ``` ```bash#CLI $ bun build --entrypoints ./index.ts # the bundle will be printed to stdout #