diff --git a/docs/bundler/executables.mdx b/docs/bundler/executables.mdx
index ec4314d6df..16c623424f 100644
--- a/docs/bundler/executables.mdx
+++ b/docs/bundler/executables.mdx
@@ -5,18 +5,28 @@ description: "Generate standalone executables from TypeScript or JavaScript file
Bun's bundler implements a `--compile` flag for generating a standalone binary from a TypeScript or JavaScript file.
-
-
-```bash terminal icon="terminal"
-bun build ./cli.ts --compile --outfile mycli
-```
+
+
+ ```bash terminal icon="terminal"
+ bun build ./cli.ts --compile --outfile mycli
+ ```
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ await Bun.build({
+ entrypoints: ["./cli.ts"],
+ compile: {
+ outfile: "./mycli",
+ },
+ });
+ ```
+
+
```ts cli.ts icon="/icons/typescript.svg"
console.log("Hello world!");
```
-
-
This bundles `cli.ts` into an executable that can be executed directly:
```bash terminal icon="terminal"
@@ -37,49 +47,157 @@ The `--target` flag lets you compile your standalone executable for a different
To build for Linux x64 (most servers):
-```bash icon="terminal" terminal
-bun build --compile --target=bun-linux-x64 ./index.ts --outfile myapp
+
+
+ ```bash icon="terminal" terminal
+ bun build --compile --target=bun-linux-x64 ./index.ts --outfile myapp
-# To support CPUs from before 2013, use the baseline version (nehalem)
-bun build --compile --target=bun-linux-x64-baseline ./index.ts --outfile myapp
+ # To support CPUs from before 2013, use the baseline version (nehalem)
+ bun build --compile --target=bun-linux-x64-baseline ./index.ts --outfile myapp
-# To explicitly only support CPUs from 2013 and later, use the modern version (haswell)
-# modern is faster, but baseline is more compatible.
-bun build --compile --target=bun-linux-x64-modern ./index.ts --outfile myapp
-```
+ # To explicitly only support CPUs from 2013 and later, use the modern version (haswell)
+ # modern is faster, but baseline is more compatible.
+ bun build --compile --target=bun-linux-x64-modern ./index.ts --outfile myapp
+ ```
+
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ // Standard Linux x64
+ await Bun.build({
+ entrypoints: ["./index.ts"],
+ compile: {
+ target: "bun-linux-x64",
+ outfile: "./myapp",
+ },
+ });
+
+ // Baseline (pre-2013 CPUs)
+ await Bun.build({
+ entrypoints: ["./index.ts"],
+ compile: {
+ target: "bun-linux-x64-baseline",
+ outfile: "./myapp",
+ },
+ });
+
+ // Modern (2013+ CPUs, faster)
+ await Bun.build({
+ entrypoints: ["./index.ts"],
+ compile: {
+ target: "bun-linux-x64-modern",
+ outfile: "./myapp",
+ },
+ });
+ ```
+
+
+
To build for Linux ARM64 (e.g. Graviton or Raspberry Pi):
-```bash icon="terminal" terminal
-# Note: the default architecture is x64 if no architecture is specified.
-bun build --compile --target=bun-linux-arm64 ./index.ts --outfile myapp
-```
+
+
+ ```bash icon="terminal" terminal
+ # Note: the default architecture is x64 if no architecture is specified.
+ bun build --compile --target=bun-linux-arm64 ./index.ts --outfile myapp
+ ```
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ await Bun.build({
+ entrypoints: ["./index.ts"],
+ compile: {
+ target: "bun-linux-arm64",
+ outfile: "./myapp",
+ },
+ });
+ ```
+
+
To build for Windows x64:
-```bash icon="terminal" terminal
-bun build --compile --target=bun-windows-x64 ./path/to/my/app.ts --outfile myapp
+
+
+ ```bash icon="terminal" terminal
+ bun build --compile --target=bun-windows-x64 ./path/to/my/app.ts --outfile myapp
-# To support CPUs from before 2013, use the baseline version (nehalem)
-bun build --compile --target=bun-windows-x64-baseline ./path/to/my/app.ts --outfile myapp
+ # To support CPUs from before 2013, use the baseline version (nehalem)
+ bun build --compile --target=bun-windows-x64-baseline ./path/to/my/app.ts --outfile myapp
-# To explicitly only support CPUs from 2013 and later, use the modern version (haswell)
-bun build --compile --target=bun-windows-x64-modern ./path/to/my/app.ts --outfile myapp
+ # To explicitly only support CPUs from 2013 and later, use the modern version (haswell)
+ bun build --compile --target=bun-windows-x64-modern ./path/to/my/app.ts --outfile myapp
-# note: if no .exe extension is provided, Bun will automatically add it for Windows executables
-```
+ # note: if no .exe extension is provided, Bun will automatically add it for Windows executables
+ ```
+
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ // Standard Windows x64
+ await Bun.build({
+ entrypoints: ["./path/to/my/app.ts"],
+ compile: {
+ target: "bun-windows-x64",
+ outfile: "./myapp", // .exe added automatically
+ },
+ });
+
+ // Baseline or modern variants
+ await Bun.build({
+ entrypoints: ["./path/to/my/app.ts"],
+ compile: {
+ target: "bun-windows-x64-baseline",
+ outfile: "./myapp",
+ },
+ });
+ ```
+
+
+
To build for macOS arm64:
-```bash icon="terminal" terminal
-bun build --compile --target=bun-darwin-arm64 ./path/to/my/app.ts --outfile myapp
-```
+
+
+ ```bash icon="terminal" terminal
+ bun build --compile --target=bun-darwin-arm64 ./path/to/my/app.ts --outfile myapp
+ ```
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ await Bun.build({
+ entrypoints: ["./path/to/my/app.ts"],
+ compile: {
+ target: "bun-darwin-arm64",
+ outfile: "./myapp",
+ },
+ });
+ ```
+
+
To build for macOS x64:
-```bash icon="terminal" terminal
-bun build --compile --target=bun-darwin-x64 ./path/to/my/app.ts --outfile myapp
-```
+
+
+ ```bash icon="terminal" terminal
+ bun build --compile --target=bun-darwin-x64 ./path/to/my/app.ts --outfile myapp
+ ```
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ await Bun.build({
+ entrypoints: ["./path/to/my/app.ts"],
+ compile: {
+ target: "bun-darwin-x64",
+ outfile: "./myapp",
+ },
+ });
+ ```
+
+
### Supported targets
@@ -110,9 +228,27 @@ The order of the `--target` flag does not matter, as long as they're delimited b
Use the `--define` flag to inject build-time constants into your executable, such as version numbers, build timestamps, or configuration values:
-```bash icon="terminal" terminal
-bun build --compile --define BUILD_VERSION='"1.2.3"' --define BUILD_TIME='"2024-01-15T10:30:00Z"' src/cli.ts --outfile mycli
-```
+
+
+ ```bash icon="terminal" terminal
+ bun build --compile --define BUILD_VERSION='"1.2.3"' --define BUILD_TIME='"2024-01-15T10:30:00Z"' src/cli.ts --outfile mycli
+ ```
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ await Bun.build({
+ entrypoints: ["./src/cli.ts"],
+ compile: {
+ outfile: "./mycli",
+ },
+ define: {
+ BUILD_VERSION: JSON.stringify("1.2.3"),
+ BUILD_TIME: JSON.stringify("2024-01-15T10:30:00Z"),
+ },
+ });
+ ```
+
+
These constants are embedded directly into your compiled binary at build time, providing zero runtime overhead and enabling dead code elimination optimizations.
@@ -133,17 +269,50 @@ With compiled executables, you can move that cost from runtime to build-time.
When deploying to production, we recommend the following:
-```bash icon="terminal" terminal
-bun build --compile --minify --sourcemap ./path/to/my/app.ts --outfile myapp
-```
+
+
+ ```bash icon="terminal" terminal
+ bun build --compile --minify --sourcemap ./path/to/my/app.ts --outfile myapp
+ ```
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ await Bun.build({
+ entrypoints: ["./path/to/my/app.ts"],
+ compile: {
+ outfile: "./myapp",
+ },
+ minify: true,
+ sourcemap: "linked",
+ });
+ ```
+
+
### Bytecode compilation
To improve startup time, enable bytecode compilation:
-```bash icon="terminal" terminal
-bun build --compile --minify --sourcemap --bytecode ./path/to/my/app.ts --outfile myapp
-```
+
+
+ ```bash icon="terminal" terminal
+ bun build --compile --minify --sourcemap --bytecode ./path/to/my/app.ts --outfile myapp
+ ```
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ await Bun.build({
+ entrypoints: ["./path/to/my/app.ts"],
+ compile: {
+ outfile: "./myapp",
+ },
+ minify: true,
+ sourcemap: "linked",
+ bytecode: true,
+ });
+ ```
+
+
Using bytecode compilation, `tsc` starts 2x faster:
@@ -172,9 +341,24 @@ The `--bytecode` argument enables bytecode compilation. Every time you run JavaS
**`--compile-exec-argv="args"`** - Embed runtime arguments that are available via `process.execArgv`:
-```bash icon="terminal" terminal
-bun build --compile --compile-exec-argv="--smol --user-agent=MyBot" ./app.ts --outfile myapp
-```
+
+
+ ```bash icon="terminal" terminal
+ bun build --compile --compile-exec-argv="--smol --user-agent=MyBot" ./app.ts --outfile myapp
+ ```
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ await Bun.build({
+ entrypoints: ["./app.ts"],
+ compile: {
+ execArgv: ["--smol", "--user-agent=MyBot"],
+ outfile: "./myapp",
+ },
+ });
+ ```
+
+
```ts app.ts icon="/icons/typescript.svg"
// In the compiled app
@@ -213,35 +397,39 @@ bun build --compile --compile-autoload-tsconfig --compile-autoload-package-json
To disable `.env` or `bunfig.toml` loading for deterministic execution:
-```bash icon="terminal" terminal
-# Disable .env loading
-bun build --compile --no-compile-autoload-dotenv ./app.ts --outfile myapp
+
+
+ ```bash icon="terminal" terminal
+ # Disable .env loading
+ bun build --compile --no-compile-autoload-dotenv ./app.ts --outfile myapp
-# Disable bunfig.toml loading
-bun build --compile --no-compile-autoload-bunfig ./app.ts --outfile myapp
+ # Disable bunfig.toml loading
+ bun build --compile --no-compile-autoload-bunfig ./app.ts --outfile myapp
-# Disable all config loading
-bun build --compile --no-compile-autoload-dotenv --no-compile-autoload-bunfig ./app.ts --outfile myapp
-```
+ # Disable all config loading
+ bun build --compile --no-compile-autoload-dotenv --no-compile-autoload-bunfig ./app.ts --outfile myapp
+ ```
-### JavaScript API
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ await Bun.build({
+ entrypoints: ["./app.ts"],
+ compile: {
+ // tsconfig.json and package.json are disabled by default
+ autoloadTsconfig: true, // Enable tsconfig.json loading
+ autoloadPackageJson: true, // Enable package.json loading
-You can also configure autoloading via the JavaScript API:
+ // .env and bunfig.toml are enabled by default
+ autoloadDotenv: false, // Disable .env loading
+ autoloadBunfig: false, // Disable bunfig.toml loading
+ outfile: "./myapp",
+ },
+ });
+ ```
-```ts
-await Bun.build({
- entrypoints: ["./app.ts"],
- compile: {
- // tsconfig.json and package.json are disabled by default
- autoloadTsconfig: true, // Enable tsconfig.json loading
- autoloadPackageJson: true, // Enable package.json loading
-
- // .env and bunfig.toml are enabled by default
- autoloadDotenv: false, // Disable .env loading
- autoloadBunfig: false, // Disable bunfig.toml loading
- },
-});
-```
+
+
---
@@ -340,9 +528,23 @@ body {
To build this into a single executable:
-```bash terminal icon="terminal"
-bun build --compile ./server.ts --outfile myapp
-```
+
+
+ ```bash terminal icon="terminal"
+ bun build --compile ./server.ts --outfile myapp
+ ```
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ await Bun.build({
+ entrypoints: ["./server.ts"],
+ compile: {
+ outfile: "./myapp",
+ },
+ });
+ ```
+
+
This creates a self-contained binary that includes:
@@ -365,11 +567,25 @@ For more details on building full-stack applications with Bun, see the [full-sta
## Worker
-To use workers in a standalone executable, add the worker's entrypoint to the CLI arguments:
+To use workers in a standalone executable, add the worker's entrypoint to the build:
-```bash terminal icon="terminal"
-bun build --compile ./index.ts ./my-worker.ts --outfile myapp
-```
+
+
+ ```bash terminal icon="terminal"
+ bun build --compile ./index.ts ./my-worker.ts --outfile myapp
+ ```
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ await Bun.build({
+ entrypoints: ["./index.ts", "./my-worker.ts"],
+ compile: {
+ outfile: "./myapp",
+ },
+ });
+ ```
+
+
Then, reference the worker in your code:
@@ -590,11 +806,32 @@ Unfortunately, if you're using `@mapbox/node-pre-gyp` or other similar tools, yo
### Embed directories
-To embed a directory with `bun build --compile`, use a shell glob in your `bun build` command:
+To embed a directory with `bun build --compile`, include file patterns in your build:
-```bash terminal icon="terminal"
-bun build --compile ./index.ts ./public/**/*.png
-```
+
+
+ ```bash terminal icon="terminal"
+ bun build --compile ./index.ts ./public/**/*.png
+ ```
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ import { Glob } from "bun";
+
+ // Expand glob pattern to file list
+ const glob = new Glob("./public/**/*.png");
+ const pngFiles = Array.from(glob.scanSync("."));
+
+ await Bun.build({
+ entrypoints: ["./index.ts", ...pngFiles],
+ compile: {
+ outfile: "./myapp",
+ },
+ });
+ ```
+
+
+
Then, you can reference the files in your code:
@@ -670,26 +907,118 @@ serve({
By default, embedded files have a content hash appended to their name. This is useful for situations where you want to serve the file from a URL or CDN and have fewer cache invalidation issues. But sometimes, this is unexpected and you might want the original name instead:
-To disable the content hash, pass `--asset-naming` to `bun build --compile` like this:
+To disable the content hash, configure asset naming:
-```bash terminal icon="terminal"
-bun build --compile --asset-naming="[name].[ext]" ./index.ts
-```
+
+
+ ```bash terminal icon="terminal"
+ bun build --compile --asset-naming="[name].[ext]" ./index.ts
+ ```
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ await Bun.build({
+ entrypoints: ["./index.ts"],
+ compile: {
+ outfile: "./myapp",
+ },
+ naming: {
+ asset: "[name].[ext]",
+ },
+ });
+ ```
+
+
---
## Minification
-To trim down the size of the executable a little, pass `--minify` to `bun build --compile`. This uses Bun's minifier to reduce the code size. Overall though, Bun's binary is still way too big and we need to make it smaller.
+To trim down the size of the executable, enable minification:
+
+
+
+ ```bash terminal icon="terminal"
+ bun build --compile --minify ./index.ts --outfile myapp
+ ```
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ await Bun.build({
+ entrypoints: ["./index.ts"],
+ compile: {
+ outfile: "./myapp",
+ },
+ minify: true, // Enable all minification
+ });
+
+ // Or granular control:
+ await Bun.build({
+ entrypoints: ["./index.ts"],
+ compile: {
+ outfile: "./myapp",
+ },
+ minify: {
+ whitespace: true,
+ syntax: true,
+ identifiers: true,
+ },
+ });
+ ```
+
+
+
+
+This uses Bun's minifier to reduce the code size. Overall though, Bun's binary is still way too big and we need to make it smaller.
---
## Windows-specific flags
-When compiling a standalone executable on Windows, there are two platform-specific options that can be used to customize metadata on the generated `.exe` file:
+When compiling a standalone executable on Windows, there are platform-specific options to customize metadata on the generated `.exe` file:
-- `--windows-icon=path/to/icon.ico` to customize the executable file icon.
-- `--windows-hide-console` to disable the background terminal, which can be used for applications that do not need a TTY.
+
+
+ ```bash terminal icon="terminal"
+ # Custom icon
+ bun build --compile --windows-icon=path/to/icon.ico ./app.ts --outfile myapp
+
+ # Hide console window (for GUI apps)
+ bun build --compile --windows-hide-console ./app.ts --outfile myapp
+ ```
+
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ await Bun.build({
+ entrypoints: ["./app.ts"],
+ compile: {
+ outfile: "./myapp",
+ windows: {
+ icon: "./path/to/icon.ico",
+ hideConsole: true,
+ // Additional Windows metadata:
+ title: "My Application",
+ publisher: "My Company",
+ version: "1.0.0",
+ description: "A standalone Windows application",
+ copyright: "Copyright 2024",
+ },
+ },
+ });
+ ```
+
+
+
+Available Windows options:
+
+- `icon` - Path to `.ico` file for the executable icon
+- `hideConsole` - Disable the background terminal (for GUI apps)
+- `title` - Application title in file properties
+- `publisher` - Publisher name in file properties
+- `version` - Version string in file properties
+- `description` - Description in file properties
+- `copyright` - Copyright notice in file properties
These flags currently cannot be used when cross-compiling because they depend on Windows APIs.
@@ -746,9 +1075,23 @@ codesign -vvv --verify ./myapp
Standalone executables support code splitting. Use `--compile` with `--splitting` to create an executable that loads code-split chunks at runtime.
-```bash
-bun build --compile --splitting ./src/entry.ts --outdir ./build
-```
+
+
+ ```bash terminal icon="terminal"
+ bun build --compile --splitting ./src/entry.ts --outdir ./build
+ ```
+
+
+ ```ts build.ts icon="/icons/typescript.svg"
+ await Bun.build({
+ entrypoints: ["./src/entry.ts"],
+ compile: true,
+ splitting: true,
+ outdir: "./build",
+ });
+ ```
+
+
@@ -777,6 +1120,50 @@ Lazy module loaded
---
+## Using plugins
+
+Plugins work with standalone executables, allowing you to transform files during the build process:
+
+```ts build.ts icon="/icons/typescript.svg"
+import type { BunPlugin } from "bun";
+
+const envPlugin: BunPlugin = {
+ name: "env-loader",
+ setup(build) {
+ build.onLoad({ filter: /\.env\.json$/ }, async args => {
+ // Transform .env.json files into validated config objects
+ const env = await Bun.file(args.path).json();
+
+ return {
+ contents: `export default ${JSON.stringify(env)};`,
+ loader: "js",
+ };
+ });
+ },
+};
+
+await Bun.build({
+ entrypoints: ["./cli.ts"],
+ compile: {
+ outfile: "./mycli",
+ },
+ plugins: [envPlugin],
+});
+```
+
+Example use case - embedding environment config at build time:
+
+```ts cli.ts icon="/icons/typescript.svg"
+import config from "./config.env.json";
+
+console.log(`Running in ${config.environment} mode`);
+console.log(`API endpoint: ${config.apiUrl}`);
+```
+
+Plugins can perform any transformation: compile YAML/TOML configs, inline SQL queries, generate type-safe API clients, or preprocess templates. Refer to the [plugin documentation](/bundler/plugins) for more details.
+
+---
+
## Unsupported CLI arguments
Currently, the `--compile` flag can only accept a single entrypoint at a time and does not support the following flags:
@@ -785,3 +1172,106 @@ Currently, the `--compile` flag can only accept a single entrypoint at a time an
- `--public-path`
- `--target=node` or `--target=browser`
- `--no-bundle` - we always bundle everything into the executable.
+
+---
+
+## API reference
+
+The `compile` option in `Bun.build()` accepts three forms:
+
+```ts title="types" icon="/icons/typescript.svg"
+interface BuildConfig {
+ entrypoints: string[];
+ compile: boolean | Bun.Build.Target | CompileBuildOptions;
+ // ... other BuildConfig options (minify, sourcemap, define, plugins, etc.)
+}
+
+interface CompileBuildOptions {
+ target?: Bun.Build.Target; // Cross-compilation target
+ outfile?: string; // Output executable path
+ execArgv?: string[]; // Runtime arguments (process.execArgv)
+ autoloadTsconfig?: boolean; // Load tsconfig.json (default: false)
+ autoloadPackageJson?: boolean; // Load package.json (default: false)
+ autoloadDotenv?: boolean; // Load .env files (default: true)
+ autoloadBunfig?: boolean; // Load bunfig.toml (default: true)
+ windows?: {
+ icon?: string; // Path to .ico file
+ hideConsole?: boolean; // Hide console window
+ title?: string; // Application title
+ publisher?: string; // Publisher name
+ version?: string; // Version string
+ description?: string; // Description
+ copyright?: string; // Copyright notice
+ };
+}
+```
+
+Usage forms:
+
+```ts icon="/icons/typescript.svg"
+// Simple boolean - compile for current platform (uses entrypoint name as output)
+compile: true
+
+// Target string - cross-compile (uses entrypoint name as output)
+compile: "bun-linux-x64"
+
+// Full options object - specify outfile and other options
+compile: {
+ target: "bun-linux-x64",
+ outfile: "./myapp",
+}
+```
+
+### Supported targets
+
+```ts title="Bun.Build.Target" icon="/icons/typescript.svg"
+type Target =
+ | "bun-darwin-x64"
+ | "bun-darwin-x64-baseline"
+ | "bun-darwin-arm64"
+ | "bun-linux-x64"
+ | "bun-linux-x64-baseline"
+ | "bun-linux-x64-modern"
+ | "bun-linux-arm64"
+ | "bun-linux-x64-musl"
+ | "bun-linux-arm64-musl"
+ | "bun-windows-x64"
+ | "bun-windows-x64-baseline"
+ | "bun-windows-x64-modern";
+```
+
+### Complete example
+
+```ts build.ts icon="/icons/typescript.svg"
+import type { BunPlugin } from "bun";
+
+const myPlugin: BunPlugin = {
+ name: "my-plugin",
+ setup(build) {
+ // Plugin implementation
+ },
+};
+
+const result = await Bun.build({
+ entrypoints: ["./src/cli.ts"],
+ compile: {
+ target: "bun-linux-x64",
+ outfile: "./dist/mycli",
+ execArgv: ["--smol"],
+ autoloadDotenv: false,
+ autoloadBunfig: false,
+ },
+ minify: true,
+ sourcemap: "linked",
+ bytecode: true,
+ define: {
+ "process.env.NODE_ENV": JSON.stringify("production"),
+ VERSION: JSON.stringify("1.0.0"),
+ },
+ plugins: [myPlugin],
+});
+
+if (result.success) {
+ console.log("Build successful:", result.outputs[0].path);
+}
+```