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.
- CLI
- JavaScript API
Why bundle?
Fewer HTTP requests
Combine dozens of modules and dependencies into a small number of self-contained bundles that load with a single request.
Code transforms
TypeScript, JSX, CSS modules, and other formats are all converted to plain JavaScript and CSS without extra tooling.
Tree shaking
Dead code is automatically eliminated. Only the exports that are actually used end up in the bundle.
Full-stack builds
Bundle both server and client code in a single command, including HTML entry points with embedded assets.
Basic example
Given these two files:- CLI
- JavaScript API
./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.
- CLI
- JavaScript API
| 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").
- CLI
- JavaScript API
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.compilerOptions.jsx from your tsconfig.json to determine how to compile JSX. You can also configure it directly in the Bun.build() API:
Bun does not perform type checking. Use
tsc --noEmit for type checking.Code splitting
When multiple entrypoints share dependencies, use--splitting to extract them into shared chunks, reducing duplication.
- CLI
- JavaScript API
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./*@__PURE__*/ annotations to mark side-effect-free function calls for elimination when their result is unused:
Sourcemaps
- CLI
- JavaScript API
| 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 theenv option to control how process.env.* references are handled in the bundle.
- CLI
- JavaScript API
JavaScript API: Bun.build()
The Bun.build() API returns a Promise<BuildOutput>:
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 |
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: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 (
--bundleis not needed) --platformis renamed to--target--outbaseis renamed to--root--asset-namesis 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