new·Earn with mozg — 20% of every monthSend somebody here and take a fifth of every plan payment they make, for as long as they keep paying — not a bounty on the first invoice. Your handle is the link, the window is thirty days, and the commission lands on your balance the second they pay. Free to join: if you have signed in, you already have the link. mozg.sh/earnall news →
mozg.beta
Sign in

Bun · all subjects

bundler options & build configuration

25 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Bytecode caching --bytecode flag basic usage

Enable bytecode caching with the --bytecode flag. When compiling TypeScript's tsc with bytecode enabled, startup time improves by 2x. Without --format specified, the output format defaults to CommonJS. The build command bun build ./index.ts --target=bun --bytecode --outdir=./dist writes two files: dist/index.js (bundled JavaScript in CommonJS) and dist/index.js.jsc (the bytecode cache file). At runtime, Bun automatically detects and uses the .jsc file.

Bytecode with standalone executables --compile

When creating an executable with --compile, Bun embeds the bytecode in the binary. Both ESM and CommonJS work. For ESM: bun build ./cli.ts --compile --bytecode --format=esm --outfile=mycli. For CommonJS: bun build ./cli.ts --compile --bytecode --outfile=mycli. The resulting executable contains both the code and the bytecode.

ESM bytecode requires --compile

ESM bytecode requires --compile because Bun embeds module metadata (import/export information) in the compiled binary. With this metadata, the JavaScript engine skips parsing entirely at runtime. Without --compile, ESM bytecode would still require parsing the source to analyze module dependencies, which defeats the purpose of bytecode caching.

Bytecode depth limiting with --bytecode-depth

Use --bytecode-depth (a non-negative integer) to compile only the top N levels of nesting. Functions past that limit are compiled from source when they are first called. --bytecode-depth=0 compiles only the top-level code of each module, no nested functions. --bytecode-depth=1 compiles top-level code and the functions it declares directly. A lower depth makes the .jsc file smaller. The same option is available as bytecodeDepth in Bun.build.

Combine bytecode with minification and sourcemaps

Combine bytecode with minification and source maps using: bun build --compile --bytecode --minify --sourcemap ./cli.ts --outfile=mycli. The --minify flag reduces code size before generating bytecode (less code -> less bytecode). The --sourcemap flag preserves error reporting (errors still point to original source). The --bytecode flag eliminates parsing overhead.

bun build --loader syntax

Bun's --loader syntax differs from esbuild. Use --loader .ext:loader instead of esbuild's --loader:.ext=loader. For example: bun build app.ts --loader .svg:text instead of esbuild app.ts --bundle --loader:.svg=text.

bun build --target replaces --platform

Bun uses --target instead of esbuild's --platform for consistency with tsconfig. Bun's --target does not support neutral.

bun build --sourcemap supported values

Bun's --sourcemap flag supports linked (the default when no value is given), external, inline, and none. It does not support esbuild's both.

bun build does not support --target for syntax downleveling

Bun's bundler performs no syntactic down-leveling. The esbuild --target flag is not supported.

bun build --asset-naming (renamed from --asset-names)

Bun uses --asset-naming instead of esbuild's --asset-names for consistency with naming in the JS API.

bun build --chunk-naming (renamed from --chunk-names)

Bun uses --chunk-naming instead of esbuild's --chunk-names for consistency with naming in the JS API.

bun build --entry-naming (renamed from --entry-names)

Bun uses --entry-naming instead of esbuild's --entry-names for consistency with naming in the JS API.

CLI flag syntax differences from esbuild

In Bun's CLI, boolean flags like --minify take no argument. Flags that take one value, 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.

bun build --ignore-dce-annotations

Bun uses --ignore-dce-annotations instead of esbuild's --ignore-annotations.

bun build --jsx-runtime values

Bun's --jsx-runtime flag supports "automatic" (uses jsx transform) and "classic" (uses React.createElement), instead of esbuild's --jsx.

Bun jsx configuration reads from tsconfig.json by default

Bun reads compilerOptions.jsx from tsconfig.json to determine a default for JSX. 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.

bun build --root (renamed from --outbase)

Bun uses --root instead of esbuild's --outbase.

bun build --tsconfig-override

Bun uses --tsconfig-override instead of esbuild's --tsconfig.

Bun bundler tree-shaking always enabled

Tree-shaking is always true in Bun. Bun also tree-shakes the exports of import() / require() targets down to the names the importing code reads (see splitting). esbuild keeps every export of a dynamically imported module.

bun build CLI example

The Bun CLI for building is: bun build <entrypoint> --outdir=out. Unlike esbuild, no --bundle flag is needed.

bun build --feature flag for compile-time dead-code elimination

Bun has a --feature flag that is Bun-specific. It enables feature flags for compile-time dead-code elimination through import { feature } from "bun:bundle".

bun build --no-bundle to disable bundling

Bun always bundles by default. Use the --no-bundle flag to disable bundling.

bun build --define syntax (no colon)

Bun's --define syntax does not use a colon, unlike esbuild. Use --define K=V instead of esbuild's --define:K=V.

bun build --external syntax (no colon)

Bun's --external syntax does not use a colon, unlike esbuild. Use --external <pkg> instead of esbuild's --external:<pkg>.

bun build --format supported values

Bun's --format flag supports "esm", "cjs", and "iife". esbuild defaults to "iife".

Give your agent this brain