interface

BuildConfig

interface BuildConfig

  • allowUnresolved?: string[]

    Control whether dynamic import(), require(), or require.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 like import(fn()).

  • banner?: string

    Add a banner to the bundled code such as "use client";

  • 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"

  • bytecodeDepth?: number

    How many levels of nested functions to compile to bytecode ahead of time. 0 compiles 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 become data: URIs. All entrypoints must be HTML files. Cannot be used with splitting.

    // 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 exports conditions used when resolving imports

    Equivalent to --conditions in bun build or bun run.

    https://nodejs.org/api/packages.html#exports

  • define?: Record<string, string>
  • drop?: string[]

    Drop function calls to matching property accesses.

  • emitDCEAnnotations?: boolean

    Force emitting @PURE annotations even if minify.whitespace is true.

  • entrypoints: string[]

    List of entrypoints, usually file paths

  • 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 converting process.env.FOO references 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"],
    })
  • external?: string[]
  • features?: string[]

    Enable feature flags for dead-code elimination via import { feature } from "bun:bundle".

    When feature("FLAG_NAME") is called, it returns true if FLAG_NAME is in this array, or false otherwise. This enables static dead-code elimination at bundle time.

    Equivalent to the CLI --feature flag.

    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 string
    • Blob - A Blob containing the source code
    • NodeJS.TypedArray - A typed array (e.g., Uint8Array) containing the source code
    • ArrayBufferLike - 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!";
          }
        `,
      },
    });
  • footer?: string

    Add a footer to the bundled code such as a comment block like

    // made with bun!

  • 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

  • loader?: {
    __index[
    key: string
    ]: Loader;
    }
  • 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 it import()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. Requires splitting: 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/false to enable/disable all minification options. Alternatively, you can pass an object for granular control over certain minifications.

  • modulePreload?: boolean

    With splitting and target: "browser", HTML entrypoints get a <link rel="modulepreload"> for every chunk their script statically imports, and each import() 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": false in its package.json.

    await Bun.build({
      entrypoints: ['./app.ts'],
      optimizeImports: ['antd', '@mui/material', 'lodash-es'],
    });
  • outdir?: string
  • packages?: 'external' | 'bundle'
  • publicPath?: string
  • reactCompiler?: boolean

    Run the React Compiler over .jsx/.tsx source files, automatically memoizing components and hooks.

  • reactCompilerOutputMode?: 'client' | 'ssr'

    Output mode for the React Compiler. "ssr" skips memoization (the useMemoCache runtime) 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.

  • root?: string
  • sourcemap?: boolean | 'linked' | 'external' | 'none' | 'inline'

    Specifies if and how to generate source maps.

    • "none" - No source maps are generated
    • "linked" - A separate *.ext.map file is generated alongside each *.ext file. A //# sourceMappingURL comment is added to the output file to link the two. Requires outdir to 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 //# sourceMappingURL comment is added to the output file.

    true and false are aliases for "inline" and "none", respectively.

  • splitRequire?: boolean

    With splitting and target: "bun", every require() of a bundled ES module is a chunk boundary too. The call stays synchronous: it is emitted as import.meta.require("./chunk-…js") and the chunk is evaluated when the call runs, so a require() inside a function that never runs costs nothing at startup. Set to false to keep such modules inlined in the calling chunk. No effect for other targets.

  • splitting?: boolean

    Enable code splitting

  • 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}
  • treeShaking?: boolean

    Whether to enable tree-shaking (removal of unreferenced top-level declarations and unused exports). Defaults to true. Set to false to 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-override in the CLI.

    await Bun.build({
      entrypoints: ['./src/index.ts'],
      tsconfig: './custom-tsconfig.json'
    });