interface
BuildConfig
interface BuildConfig
- allowUnresolved?: string[]
Control whether dynamic
import(),require(), orrequire.resolve()specifiers (non-literal arguments like`./locales/${lang}.json`) are allowed to pass through to runtime without being bundled.["*"](default) — allow all dynamic specifiers[]— fail the build on any dynamic specifier["./locales/*.json", ...]— allow only specifiers whose static template parts match one of these glob patterns
Add
""to the list to allow fully opaque specifiers likeimport(fn()). - bytecode?: boolean
Generate bytecode for the output. This can dramatically improve cold start times, but makes the final output larger and slightly increases memory usage.
- CommonJS: works with or without
compile: true - ESM: requires
compile: true
Without an explicit
format, defaults to CommonJS.Must be
target: "bun" - CommonJS: works with or without
- bytecodeDepth?: number
How many levels of nested functions to compile to bytecode ahead of time.
0compiles only each module's top-level code; nested functions past the limit are compiled from source when first called. Lower values make the bytecode smaller at the cost of some startup work.Must be a non-negative integer. Only used when
bytecode: true. - compile?: boolean | CompileTarget | CompileBuildOptions
Create a standalone executable or self-contained HTML.
When
true, creates an executable for the current platform. When a target string, creates an executable for that platform.When used with
target: "browser", produces self-contained HTML files with all scripts, styles, and assets inlined. All<script>tags become inline<script>with bundled code, all<link rel="stylesheet">tags become inline<style>tags, and all asset references becomedata:URIs. All entrypoints must be HTML files. Cannot be used withsplitting.// Create executable for current platform await Bun.build({ entrypoints: ['./app.js'], compile: { target: 'linux-x64', }, outfile: './my-app' }); // Cross-compile for Linux x64 await Bun.build({ entrypoints: ['./app.js'], compile: 'linux-x64', outfile: './my-app' }); // Produce self-contained HTML await Bun.build({ entrypoints: ['./index.html'], target: 'browser', compile: true, }); - conditions?: string | string[]
package.json
exportsconditions used when resolving importsEquivalent to
--conditionsinbun buildorbun run.https://nodejs.org/api/packages.html#exports
- env?: 'inline' | 'disable' | `${string}*`
Controls how environment variables are handled during bundling.
Can be one of:
"inline": Injects environment variables into the bundled output by convertingprocess.env.FOOreferences to string literals containing the actual environment variable values"disable": Disables environment variable injection entirely- A string ending in
*: Inlines environment variables that match the given prefix. For example,"MY_PUBLIC_*"only includes env vars starting with "MY_PUBLIC_"
Bun.build({ env: "MY_PUBLIC_*", entrypoints: ["src/index.ts"], }) - features?: string[]
Enable feature flags for dead-code elimination via
import { feature } from "bun:bundle".When
feature("FLAG_NAME")is called, it returnstrueif FLAG_NAME is in this array, orfalseotherwise. This enables static dead-code elimination at bundle time.Equivalent to the CLI
--featureflag.await Bun.build({ entrypoints: ['./src/index.ts'], features: ['FEATURE_A', 'FEATURE_B'], }); - files?: Record<string, string | ArrayBufferLike | TypedArray<ArrayBufferLike> | Blob>
A map of file paths to their contents for in-memory bundling.
Use this to bundle virtual files that don't exist on disk, or override the contents of files that do exist on disk. The keys are file paths (which should match how they're imported) and the values are the file contents.
File contents can be provided as:
string- The source code as a stringBlob- A Blob containing the source codeNodeJS.TypedArray- A typed array (e.g.,Uint8Array) containing the source codeArrayBufferLike- An ArrayBuffer containing the source code
// Bundle entirely from memory (no files on disk needed) await Bun.build({ entrypoints: ["/app/index.ts"], files: { "/app/index.ts": ` import { helper } from "./helper.ts"; console.log(helper()); `, "/app/helper.ts": ` export function helper() { return "Hello from memory!"; } `, }, }); - format?: 'esm' | 'cjs' | 'iife'
Output module format. Top-level await is only supported for
"esm".Can be:
"esm""cjs"(experimental)"iife"(experimental)
- ignoreDCEAnnotations?: boolean
Ignore dead code elimination/tree-shaking annotations such as @PURE and package.json "sideEffects" fields. This should only be used as a temporary workaround for incorrect annotations in libraries.
- jsx?: { development: boolean; factory: string; fragment: string; importSource: string; runtime: 'classic' | 'automatic'; sideEffects: boolean }
JSX configuration options
- metafile?: boolean
Generate a JSON file containing metadata about the build.
The metafile contains information about inputs, outputs, imports, and exports which can be used for bundle analysis, visualization, or integration with other tools.
When
true, the metafile JSON string is included in the BuildOutput.metafile property.const result = await Bun.build({ entrypoints: ['./src/index.ts'], outdir: './dist', metafile: true, }); // Write metafile to disk for analysis if (result.metafile) { await Bun.write('./dist/meta.json', result.metafile); } // Parse and analyze the metafile const meta = JSON.parse(result.metafile!); console.log('Input files:', Object.keys(meta.inputs)); console.log('Output files:', Object.keys(meta.outputs)); - minChunkSize?: number
With
splitting, chunks that are always loaded together are folded into one (for example, code shared by an entry point and a module itimport()s lives in the entry point's chunk). This option additionally folds chunks whose combined source size is below this many bytes and whose modules have no top-level side effects into a chunk loaded by a superset of their importers, so fewer modules are loaded at runtime. Nothing lazy becomes eager and no side effect runs earlier; the chunk that absorbs a folded chunk exports the symbols other chunks import from it. Requiressplitting: true. CLI:--min-chunk-size. For browser builds, where every chunk is a request, 16384 is a good value. - minify?: boolean | { identifiers: boolean; keepNames: boolean; syntax: boolean; whitespace: boolean }
Whether to enable minification.
Use
true/falseto enable/disable all minification options. Alternatively, you can pass an object for granular control over certain minifications. - modulePreload?: boolean
With
splittingandtarget: "browser", HTML entrypoints get a<link rel="modulepreload">for every chunk their script statically imports, and eachimport()first adds one for every chunk its target statically imports, so a chunk's dependencies download in parallel instead of one import depth per round trip. CLI:--no-module-preload. - naming?: string | { asset: string; chunk: string; entry: string }
Output file name templates. Tokens:
[dir],[name],[ext],[target], and[hash](8 characters of the content hash, more when two outputs would otherwise share a name) or[hash9]…[hash13]for a wider minimum. - optimizeImports?: string[]
List of package names whose barrel files (re-export index files) should be optimized. When a named import comes from one of these packages, only the submodules actually used are parsed — unused re-exports are skipped entirely.
This is also enabled automatically for any package with
"sideEffects": falsein itspackage.json.await Bun.build({ entrypoints: ['./app.ts'], optimizeImports: ['antd', '@mui/material', 'lodash-es'], }); - reactCompiler?: boolean
Run the React Compiler over
.jsx/.tsxsource files, automatically memoizing components and hooks. - reactCompilerOutputMode?: 'client' | 'ssr'
Output mode for the React Compiler.
"ssr"skips memoization (theuseMemoCacheruntime) for server-rendered output.Only applies when reactCompiler is
true. - reactFastRefresh?: boolean
Enable React Fast Refresh transform.
This adds the necessary code transformations for React Fast Refresh (hot module replacement for React components), but does not emit hot-module code itself.
- sourcemap?: boolean | 'linked' | 'external' | 'none' | 'inline'
Specifies if and how to generate source maps.
"none"- No source maps are generated"linked"- A separate*.ext.mapfile is generated alongside each*.extfile. A//# sourceMappingURLcomment is added to the output file to link the two. Requiresoutdirto be set."inline"- an inline source map is appended to the output file."external"- Generate a separate source map file for each input file. No//# sourceMappingURLcomment is added to the output file.
trueandfalseare aliases for"inline"and"none", respectively. - splitRequire?: boolean
With
splittingandtarget: "bun", everyrequire()of a bundled ES module is a chunk boundary too. The call stays synchronous: it is emitted asimport.meta.require("./chunk-…js")and the chunk is evaluated when the call runs, so arequire()inside a function that never runs costs nothing at startup. Set tofalseto keep such modules inlined in the calling chunk. No effect for other targets. - throw?: boolean
- When set to
true, the returned promise rejects with an AggregateError when a build failure happens. - When set to
false, returns a BuildOutput with{success: false}
- When set to
- treeShaking?: boolean
Whether to enable tree-shaking (removal of unreferenced top-level declarations and unused exports). Defaults to
true. Set tofalseto keep dead code in the output for debugging or test fixtures. - tsconfig?: string
Custom tsconfig.json file path to use for path resolution. Equivalent to
--tsconfig-overridein the CLI.await Bun.build({ entrypoints: ['./src/index.ts'], tsconfig: './custom-tsconfig.json' });