Bundles JavaScript, TypeScript, CSS, HTML and other supported files into optimized outputs.
function
build
Build configuration options
Promise that resolves to build output containing generated artifacts and build status
Basic usage - Bundle a single entrypoint and check results
const result = await Bun.build({
entrypoints: ['./src/index.tsx'],
outdir: './dist'
});
if (!result.success) {
console.error('Build failed:', result.logs);
process.exit(1);
}
Referenced types
interface BuildConfig
- bytecode?: boolean
Generate bytecode for the output. This can dramatically improve cold start times, but will make the final output larger and slightly increase 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
- 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_*"will only include 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.
This allows you 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)); - 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. - 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'], }); - 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. - 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
- 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' });
interface BuildOutput
The output of a build
- metafile?: BuildMetafile
Metadata about the build including inputs, outputs, and their relationships.
Only present when BuildConfig.metafile is
true.The metafile contains detailed information about:
- inputs: All source files that were bundled, their byte sizes, imports, and format
- outputs: All generated output files, their byte sizes, which inputs contributed to each output, imports between chunks, and exports
This can be used for:
- Bundle size analysis and visualization
- Detecting unused code or dependencies
- Understanding the dependency graph
- Integration with bundle analyzer tools
const result = await Bun.build({ entrypoints: ['./src/index.ts'], outdir: './dist', metafile: true, }); if (result.metafile) { // Analyze input files for (const [path, input] of Object.entries(result.metafile.inputs)) { console.log(`${path}: ${input.bytes} bytes, ${input.imports.length} imports`); } // Analyze output files for (const [path, output] of Object.entries(result.metafile.outputs)) { console.log(`${path}: ${output.bytes} bytes`); for (const [inputPath, info] of Object.entries(output.inputs)) { console.log(` - ${inputPath}: ${info.bytesInOutput} bytes`); } } // Write to disk for external analysis tools await Bun.write('./dist/meta.json', JSON.stringify(result.metafile)); }