Bundling by default. Unlike esbuild, Bun bundles by default; no
--bundle flag is needed. To transpile each file
individually, use Bun.Transpiler.Bundler only. Unlike esbuild, Bun’s bundler has no built-in development server. Use it with
Bun.serve and other
runtime APIs to get the same effect. esbuild’s HTTP options don’t apply.Performance
Bun’s bundler is 1.75x faster than esbuild on esbuild’s three.js benchmark.Bundling 10 copies of three.js from scratch, with sourcemaps and minification
CLI API
terminal
--minify take no argument. Flags that take one, like --outdir <path>, can be written as --outdir out or --outdir=out. Some flags, like --define, can be repeated: --define foo=bar --define bar=baz.
| esbuild | bun build | Notes |
|---|---|---|
--bundle | n/a | Bun always bundles; use --no-bundle to disable it. |
--define:K=V | --define K=V | Small syntax difference; no colon.esbuild --define:foo=barbun build --define foo=bar |
--external:<pkg> | --external <pkg> | Small syntax difference; no colon.esbuild --external:reactbun build --external react |
--format | --format | Bun supports "esm", "cjs", and "iife". esbuild defaults to "iife". |
--loader:.ext=loader | --loader .ext:loader | Bun supports a different set of built-in loaders than esbuild; see loaders. The esbuild loaders dataurl, binary, base64, copy, and empty are not implemented.The syntax for --loader differs.esbuild app.ts --bundle --loader:.svg=textbun build app.ts --loader .svg:text |
--minify | --minify | No differences |
--outdir | --outdir | No differences |
--outfile | --outfile | No differences |
--packages | --packages | No differences |
--platform | --target | Renamed to --target for consistency with tsconfig. Does not support neutral. |
--serve | n/a | Not applicable |
--sourcemap | --sourcemap | No differences |
--splitting | --splitting | No differences |
--target | n/a | Not supported. Bun’s bundler performs no syntactic down-leveling. |
--watch | --watch | No differences |
--allow-overwrite | n/a | Overwriting is never allowed |
--analyze | n/a | Not supported |
--asset-names | --asset-naming | Renamed for consistency with naming in JS API |
--banner | --banner | Only applies to js bundles |
--footer | --footer | Only applies to js bundles |
--certfile | n/a | Not applicable |
--charset=utf8 | n/a | Not supported |
--chunk-names | --chunk-naming | Renamed for consistency with naming in JS API |
--color | n/a | Always enabled |
--drop | --drop | |
| n/a | --feature | Bun-specific. Enables feature flags for compile-time dead-code elimination through import { feature } from "bun:bundle" |
--entry-names | --entry-naming | Renamed for consistency with naming in JS API |
--global-name | n/a | Not supported |
--ignore-annotations | --ignore-dce-annotations | |
--inject | n/a | Not supported |
--jsx | --jsx-runtime <runtime> | Supports "automatic" (uses jsx transform) and "classic" (uses React.createElement) |
--jsx-dev | n/a | Bun reads compilerOptions.jsx from tsconfig.json to determine a default. If compilerOptions.jsx is "react-jsx", or if NODE_ENV=production, Bun uses the jsx transform. Otherwise, it uses jsxDEV. The bundler does not support preserve. |
--jsx-factory | --jsx-factory | |
--jsx-fragment | --jsx-fragment | |
--jsx-import-source | --jsx-import-source | |
--jsx-side-effects | n/a | JSX is always assumed to be side-effect-free |
--keep-names | --keep-names | |
--keyfile | n/a | Not applicable |
--legal-comments | n/a | Not supported |
--log-level | n/a | Not supported. This can be set in bunfig.toml as logLevel. |
--log-limit | n/a | Not supported |
--log-override:X=Y | n/a | Not supported |
--main-fields | n/a | Not supported |
--mangle-cache | n/a | Not supported |
--mangle-props | n/a | Not supported |
--mangle-quoted | n/a | Not supported |
--metafile | --metafile | |
--minify-whitespace | --minify-whitespace | |
--minify-identifiers | --minify-identifiers | |
--minify-syntax | --minify-syntax | |
--out-extension | n/a | Not supported |
--outbase | --root | |
--preserve-symlinks | n/a | Not supported |
--public-path | --public-path | |
--pure | n/a | Not supported |
--reserve-props | n/a | Not supported |
--resolve-extensions | n/a | Not supported |
--servedir | n/a | Not applicable |
--source-root | n/a | Not supported |
--sourcefile | n/a | Not supported. Bun does not support stdin input. |
--sourcemap | --sourcemap | No differences |
--sources-content | n/a | Not supported |
--supported | n/a | Not supported |
--tree-shaking | n/a | Always true |
--tsconfig | --tsconfig-override | |
--version | n/a | Run bun --version to see the version of Bun. |
JavaScript API
| esbuild.build() | Bun.build() | Notes |
|---|---|---|
absWorkingDir | n/a | Always set to process.cwd() |
alias | n/a | Not supported |
allowOverwrite | n/a | Always false |
assetNames | naming.asset | Uses the same templating syntax as esbuild, but [ext] must be included explicitly.ts<br/>Bun.build({<br/> entrypoints: ["./index.tsx"],<br/> naming: {<br/> asset: "[name].[ext]",<br/> },<br/>});<br/> |
banner | banner | Only applies to js bundles |
bundle | n/a | Always true. Use Bun.Transpiler to transpile without bundling. |
charset | n/a | Not supported |
chunkNames | naming.chunk | Uses the same templating syntax as esbuild, but [ext] must be included explicitly.ts<br/>Bun.build({<br/> entrypoints: ["./index.tsx"],<br/> naming: {<br/> chunk: "[name].[ext]",<br/> },<br/>});<br/> |
color | n/a | Bun returns logs in the logs property of the build result. |
conditions | conditions | No differences |
define | define | |
drop | drop | |
entryNames | naming or naming.entry | Bun supports a naming key that can either be a string or an object. Uses the same templating syntax as esbuild, but [ext] must be included explicitly.ts<br/>Bun.build({<br/> entrypoints: ["./index.tsx"],<br/> // when string, this is equivalent to entryNames<br/> naming: "[name].[ext]",<br/><br/> // granular naming options<br/> naming: {<br/> entry: "[name].[ext]",<br/> asset: "[name].[ext]",<br/> chunk: "[name].[ext]",<br/> },<br/>});<br/> |
entryPoints | entrypoints | Capitalization difference |
external | external | No differences |
footer | footer | Only applies to js bundles |
format | format | Supports "esm", "cjs", and "iife". |
globalName | n/a | Not supported |
ignoreAnnotations | ignoreDCEAnnotations | |
inject | n/a | Not supported |
jsx | jsx.runtime | Supports "automatic" and "classic" |
jsxDev | jsx.development | |
jsxFactory | jsx.factory | |
jsxFragment | jsx.fragment | |
jsxImportSource | jsx.importSource | |
jsxSideEffects | jsx.sideEffects | |
keepNames | minify.keepNames | |
legalComments | n/a | Not supported |
loader | loader | Bun supports a different set of built-in loaders than esbuild; see loaders. The esbuild loaders dataurl, binary, base64, copy, and empty are not implemented. |
logLevel | n/a | Not supported |
logLimit | n/a | Not supported |
logOverride | n/a | Not supported |
mainFields | n/a | Not supported |
mangleCache | n/a | Not supported |
mangleProps | n/a | Not supported |
mangleQuoted | n/a | Not supported |
metafile | metafile | |
minify | minify | In Bun, minify can be a boolean or an object.ts<br/>await Bun.build({<br/> entrypoints: ['./index.tsx'],<br/> // enable all minification<br/> minify: true<br/><br/> // granular options<br/> minify: {<br/> identifiers: true,<br/> syntax: true,<br/> whitespace: true<br/> }<br/>})<br/> |
minifyIdentifiers | minify.identifiers | See minify |
minifySyntax | minify.syntax | See minify |
minifyWhitespace | minify.whitespace | See minify |
nodePaths | n/a | Not supported |
outExtension | n/a | Not supported |
outbase | root | Different name |
outdir | outdir | No differences |
outfile | outfile | No differences |
packages | packages | No differences |
platform | target | Supports "bun", "node" and "browser" (the default). Does not support "neutral". |
plugins | plugins | Bun’s plugin API is a subset of esbuild’s. Some esbuild plugins work with Bun without modification. |
preserveSymlinks | n/a | Not supported |
publicPath | publicPath | No differences |
pure | n/a | Not supported |
reserveProps | n/a | Not supported |
resolveExtensions | n/a | Not supported |
sourceRoot | n/a | Not supported |
sourcemap | sourcemap | Supports "none", "linked", "inline", and "external" |
sourcesContent | n/a | Not supported |
splitting | splitting | No differences |
stdin | n/a | Not supported |
supported | n/a | Not supported |
target | n/a | No support for syntax downleveling |
treeShaking | treeShaking | Defaults to true |
tsconfig | tsconfig | |
write | n/a | Set to true if outdir/outfile is set, otherwise false |
Plugin API
Bun’s plugin API is designed to be esbuild-compatible. Bun doesn’t support esbuild’s entire plugin API surface, but the core functionality is implemented, and many third-party esbuild plugins work with Bun without modification.Long term, we aim for feature parity with esbuild’s API. If something doesn’t work, file an issue to help us
prioritize.
onStart, onEnd, onResolve, and onLoad; it does not implement the esbuild hooks onDispose and resolve. initialOptions is partially implemented: it’s read-only and exposes only a subset of esbuild’s options. Use config (the same thing in Bun’s BuildConfig format) instead.
onResolve
- options
- arguments
- results
- 🟢
filter - 🟢
namespace
onLoad
- options
- arguments
- results
- 🟢
filter - 🟢
namespace