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

# Bundler Overview

> Bun's fast native bundler for JavaScript, TypeScript, JSX, and CSS — with zero configuration required.

Bun includes a fast native bundler that can be used via the `bun build` CLI command or the `Bun.build()` JavaScript API. It handles TypeScript, JSX, CSS, JSON, and more out of the box without any configuration.

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    bun build ./index.ts --outdir ./out
    ```
  </Tab>

  <Tab title="JavaScript API">
    ```typescript theme={null}
    await Bun.build({
      entrypoints: ["./index.tsx"],
      outdir: "./build",
    });
    ```
  </Tab>
</Tabs>

## Why bundle?

<CardGroup cols={2}>
  <Card title="Fewer HTTP requests" icon="network-wired">
    Combine dozens of modules and dependencies into a small number of self-contained bundles that load with a single request.
  </Card>

  <Card title="Code transforms" icon="code">
    TypeScript, JSX, CSS modules, and other formats are all converted to plain JavaScript and CSS without extra tooling.
  </Card>

  <Card title="Tree shaking" icon="tree">
    Dead code is automatically eliminated. Only the exports that are actually used end up in the bundle.
  </Card>

  <Card title="Full-stack builds" icon="server">
    Bundle both server and client code in a single command, including HTML entry points with embedded assets.
  </Card>
</CardGroup>

## Basic example

Given these two files:

<CodeGroup>
  ```tsx index.tsx theme={null}
  import * as ReactDOM from "react-dom/client";
  import { Component } from "./Component";

  const root = ReactDOM.createRoot(document.getElementById("root")!);
  root.render(<Component message="Sup!" />);
  ```

  ```tsx Component.tsx theme={null}
  export function Component(props: { message: string }) {
    return <h1>{props.message}</h1>;
  }
  ```
</CodeGroup>

Build them with:

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    bun build ./index.tsx --outdir ./out
    ```
  </Tab>

  <Tab title="JavaScript API">
    ```typescript theme={null}
    await Bun.build({
      entrypoints: ["./index.tsx"],
      outdir: "./out",
    });
    ```
  </Tab>
</Tabs>

Bun writes the bundled output to `./out/index.js`, with TypeScript and JSX both transpiled automatically — no `tsconfig.json` or Babel config required.

## Targets

The `--target` flag controls module resolution and available globals.

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    bun build ./index.ts --outdir ./out --target browser
    bun build ./index.ts --outdir ./out --target bun
    bun build ./index.ts --outdir ./out --target node
    ```
  </Tab>

  <Tab title="JavaScript API">
    ```typescript theme={null}
    await Bun.build({
      entrypoints: ["./index.ts"],
      outdir: "./out",
      target: "browser", // "browser" | "bun" | "node"
    });
    ```
  </Tab>
</Tabs>

| Target    | Description                                                                                      |
| --------- | ------------------------------------------------------------------------------------------------ |
| `browser` | **Default.** Prioritizes `"browser"` export conditions. Built-in Node.js modules are polyfilled. |
| `bun`     | For bundles run by the Bun runtime. Adds a `// @bun` pragma to skip re-transpilation at startup. |
| `node`    | Prioritizes `"node"` export conditions and outputs `.mjs`.                                       |

## Output formats

Bun defaults to ESM (`"esm"`), with experimental support for CommonJS (`"cjs"`).

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    bun build ./index.tsx --outdir ./out --format esm
    bun build ./index.tsx --outdir ./out --format cjs
    ```
  </Tab>

  <Tab title="JavaScript API">
    ```typescript theme={null}
    await Bun.build({
      entrypoints: ["./index.tsx"],
      outdir: "./out",
      format: "esm", // "esm" | "cjs"
    });
    ```
  </Tab>
</Tabs>

## Key flags

| Flag                | Description                                            |
| ------------------- | ------------------------------------------------------ |
| `--outdir <dir>`    | Directory to write output files                        |
| `--outfile <file>`  | Output file path (single entrypoint only)              |
| `--target <target>` | `browser`, `bun`, or `node`                            |
| `--format <format>` | `esm` (default) or `cjs`                               |
| `--splitting`       | Enable code splitting for shared chunks                |
| `--minify`          | Enable all minification                                |
| `--sourcemap`       | Sourcemap type: `none`, `linked`, `external`, `inline` |
| `--watch`           | Rebuild on file changes                                |
| `--external <pkg>`  | Mark a package as external (not bundled)               |

## TypeScript and JSX

TypeScript and JSX are supported natively — no plugins, no configuration.

```typescript theme={null}
// TypeScript types are stripped at build time
interface User {
  name: string;
  age: number;
}

// JSX is transpiled using your tsconfig.json settings
function Greeting({ name }: User) {
  return <h1>Hello, {name}</h1>;
}
```

Bun reads `compilerOptions.jsx` from your `tsconfig.json` to determine how to compile JSX. You can also configure it directly in the `Bun.build()` API:

```typescript theme={null}
await Bun.build({
  entrypoints: ["./app.tsx"],
  outdir: "./out",
  jsx: {
    runtime: "automatic",
    importSource: "preact",
  },
});
```

<Note>Bun does not perform type checking. Use `tsc --noEmit` for type checking.</Note>

## Code splitting

When multiple entrypoints share dependencies, use `--splitting` to extract them into shared chunks, reducing duplication.

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    bun build ./entry-a.ts ./entry-b.ts --outdir ./out --splitting
    ```
  </Tab>

  <Tab title="JavaScript API">
    ```typescript theme={null}
    await Bun.build({
      entrypoints: ["./entry-a.ts", "./entry-b.ts"],
      outdir: "./out",
      splitting: true,
    });
    ```
  </Tab>
</Tabs>

Shared code is written to a content-hashed chunk file:

```
out/
├── entry-a.js
├── entry-b.js
└── chunk-2fce6291bf86559d.js
```

## Tree shaking

Tree shaking is automatic. The bundler performs dead code elimination on all builds — unused exports and unreachable branches are removed without any configuration.

```typescript theme={null}
// math.ts
export function add(a: number, b: number) { return a + b; }
export function multiply(a: number, b: number) { return a * b; } // unused

// index.ts — only imports `add`
import { add } from "./math";
console.log(add(1, 2));
// `multiply` is not included in the bundle
```

Use `/*@__PURE__*/` annotations to mark side-effect-free function calls for elimination when their result is unused:

```typescript theme={null}
const result = /*@__PURE__*/ expensiveSetup();
```

## Sourcemaps

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    bun build ./index.ts --outdir ./out --sourcemap=linked
    bun build ./index.ts --outdir ./out --sourcemap=external
    bun build ./index.ts --outdir ./out --sourcemap=inline
    ```
  </Tab>

  <Tab title="JavaScript API">
    ```typescript theme={null}
    await Bun.build({
      entrypoints: ["./index.ts"],
      outdir: "./out",
      sourcemap: "linked",
    });
    ```
  </Tab>
</Tabs>

| Value        | Description                                                        |
| ------------ | ------------------------------------------------------------------ |
| `"none"`     | No sourcemap (default)                                             |
| `"linked"`   | Separate `.js.map` file, linked via `//# sourceMappingURL` comment |
| `"external"` | Separate `.js.map` file, no comment in the bundle                  |
| `"inline"`   | Sourcemap appended inline as a base64 payload                      |

## Environment variables

Use the `env` option to control how `process.env.*` references are handled in the bundle.

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    # Inline all env vars
    bun build ./index.tsx --outdir ./out --env inline

    # Inline only vars with a specific prefix
    bun build ./index.tsx --outdir ./out --env "PUBLIC_*"
    ```
  </Tab>

  <Tab title="JavaScript API">
    ```typescript theme={null}
    await Bun.build({
      entrypoints: ["./index.tsx"],
      outdir: "./out",
      env: "PUBLIC_*",
    });
    ```
  </Tab>
</Tabs>

## JavaScript API: `Bun.build()`

The `Bun.build()` API returns a `Promise<BuildOutput>`:

```typescript theme={null}
const result = await Bun.build({
  entrypoints: ["./index.tsx"],
  outdir: "./out",
  target: "browser",
  format: "esm",
  splitting: true,
  minify: true,
  sourcemap: "linked",
  external: ["react", "react-dom"],
  define: {
    "process.env.NODE_ENV": JSON.stringify("production"),
  },
  loader: {
    ".png": "dataurl",
    ".svg": "text",
  },
});

if (!result.success) {
  for (const log of result.logs) {
    console.error(log);
  }
}

for (const output of result.outputs) {
  console.log(output.path, output.kind);
}
```

Each item in `result.outputs` is a `BuildArtifact` — a `Blob` with extra properties:

| Property    | Description                                             |
| ----------- | ------------------------------------------------------- |
| `kind`      | `"entry-point"`, `"chunk"`, `"asset"`, or `"sourcemap"` |
| `path`      | Absolute path to the file on disk                       |
| `loader`    | The loader used to process the file                     |
| `hash`      | Content hash of the file                                |
| `sourcemap` | The associated sourcemap artifact, if generated         |

If `outdir` is omitted, files are not written to disk. You can consume them as `Blob` objects or pass them directly to `new Response()`.

## Watch mode

Rebuild automatically when source files change:

```bash theme={null}
bun build ./index.tsx --outdir ./out --watch
```

## esbuild compatibility

Bun's bundler API is modeled on esbuild. Most esbuild options map directly to Bun equivalents. Key differences:

* Bun always bundles by default (`--bundle` is not needed)
* `--platform` is renamed to `--target`
* `--outbase` is renamed to `--root`
* `--asset-names` is renamed to `--asset-naming`
* No built-in dev server (use `Bun.serve()` instead)
* Bun is 1.75x faster than esbuild on the three.js benchmark

Most esbuild flags map directly — see the [esbuild documentation](https://esbuild.github.io/api/) for a full flag reference.
