Skip to main content
Bun’s bundler supports the --compile flag for generating standalone binary executables from TypeScript or JavaScript files.
bun build ./cli.ts --compile --outfile mycli
cli.ts
console.log("Hello world!");
This bundles cli.ts into an executable binary that can be executed directly:
./mycli
Hello world!
All imported files and packages are bundled into the executable, along with a copy of the Bun runtime. All built-in Bun and Node.js APIs are supported.

Cross-platform compilation

The --target flag allows you to compile standalone executables for a different operating system, architecture, or Bun version than the machine running bun build. Build for Linux x64 (most servers):
bun build --compile --target=bun-linux-x64 ./index.ts --outfile myapp

# For CPU's from before 2013, use the baseline profile (nehalem)
bun build --compile --target=bun-linux-x64-baseline ./index.ts --outfile myapp

# For CPU's from 2013 onwards only, use the modern profile (haswell)
# The modern profile is faster, but baseline is more compatible.
bun build --compile --target=bun-linux-x64-modern ./index.ts --outfile myapp
Build for Linux ARM64 (like Graviton or Raspberry Pi):
# Note: default architecture is x64 if no architecture is specified.
bun build --compile --target=bun-linux-arm64 ./index.ts --outfile myapp
Build for Windows x64:
bun build --compile --target=bun-windows-x64 ./path/to/my/app.ts --outfile myapp

# For CPU's from before 2013, use the baseline profile (nehalem)
bun build --compile --target=bun-windows-x64-baseline ./path/to/my/app.ts --outfile myapp

# For CPU's from 2013 onwards only, use the modern profile (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
Build for Windows ARM64:
bun build --compile --target=bun-windows-arm64 ./path/to/my/app.ts --outfile myapp

# note: if no .exe extension is provided, Bun will automatically add it for Windows executables
Build for macOS ARM64:
bun build --compile --target=bun-darwin-arm64 ./path/to/my/app.ts --outfile myapp
Build for macOS x64:
bun build --compile --target=bun-darwin-x64 ./path/to/my/app.ts --outfile myapp

Available targets

The following targets are available:
TargetOSArchitectureProfile
bun-linux-x64Linuxx64default
bun-linux-x64-baselineLinuxx64baseline (pre-2013)
bun-linux-x64-modernLinuxx64modern (2013+)
bun-linux-arm64LinuxARM64default
bun-windows-x64Windowsx64default
bun-windows-x64-baselineWindowsx64baseline (pre-2013)
bun-windows-x64-modernWindowsx64modern (2013+)
bun-windows-arm64WindowsARM64default
bun-darwin-arm64macOSARM64default
bun-darwin-x64macOSx64default

Embedding files

You can embed files into the executable by importing them in your code. The bundler will automatically include them.
import icon from "./icon.png";
import styles from "./styles.css";

console.log(icon); // path to the embedded file
These files are extracted to a temporary directory at runtime and can be accessed via their import paths.

Configuration options

minify

You can minify the bundled code:
bun build --compile --minify ./index.ts --outfile myapp

sourcemap

Generate source maps for debugging:
bun build --compile --sourcemap=external ./index.ts --outfile myapp
This creates a .map file alongside your executable.

splitting

Code splitting is not supported when using --compile since the output is a single executable.

Environment variables

By default, executables do NOT load .env files. You can change this behavior:
bun build --compile --env-file=.env ./index.ts --outfile myapp
Or inline environment variables at build time:
bun build --compile --define 'process.env.API_KEY="secret"' ./index.ts --outfile myapp

Command-line arguments

Your executable receives command-line arguments via process.argv:
cli.ts
const args = process.argv.slice(2);
console.log("Arguments:", args);
./mycli arg1 arg2 --flag
# Arguments: [ 'arg1', 'arg2', '--flag' ]

Size considerations

Standalone executables include the Bun runtime, so they start at around 50-90 MB depending on the target platform. This size includes:
  • The Bun JavaScript runtime
  • JavaScriptCore engine
  • Your bundled code and dependencies
  • Any embedded assets
You can reduce size with:
  • --minify to compress your code
  • --external to exclude large dependencies
  • Tree shaking (automatic) to remove unused code

Deployment

Standalone executables are single-file deployables with no dependencies:
  1. Build for your target platform
  2. Copy the executable to your server
  3. Set executable permissions (Unix): chmod +x myapp
  4. Run: ./myapp
No need to install Bun or Node.js on the deployment target.

Troubleshooting

Large binary size

If your executable is larger than expected:
  • Check for unintended imports of large dependencies
  • Use --external for dependencies you want to load at runtime
  • Enable --minify to compress code

Runtime errors

If your executable fails at runtime:
  • Test your code with bun run before compiling
  • Check that all file paths are relative or properly configured
  • Verify embedded assets are imported correctly

Cross-compilation issues

When building for a different platform:
  • Ensure you’re using the correct --target value
  • Test on the target platform before deploying
  • Some native modules may not work when cross-compiled

Examples

Simple CLI tool

cli.ts
#!/usr/bin/env bun
import { parseArgs } from "util";

const { values } = parseArgs({
  args: process.argv.slice(2),
  options: {
    name: { type: "string", short: "n" },
  },
});

console.log(`Hello, ${values.name || "World"}!`);
bun build --compile ./cli.ts --outfile hello
./hello --name Bun
# Hello, Bun!

HTTP server

server.ts
const server = Bun.serve({
  port: 3000,
  fetch(req) {
    return new Response("Hello from Bun!");
  },
});

console.log(`Server running at http://localhost:${server.port}`);
bun build --compile ./server.ts --outfile server
./server
# Server running at http://localhost:3000

With embedded assets

app.ts
import logo from "./logo.png";
import template from "./template.html" with { type: "text" };

const server = Bun.serve({
  port: 3000,
  fetch(req) {
    const url = new URL(req.url);
    if (url.pathname === "/") {
      return new Response(template, {
        headers: { "Content-Type": "text/html" },
      });
    }
    if (url.pathname === "/logo.png") {
      return new Response(Bun.file(logo));
    }
    return new Response("Not found", { status: 404 });
  },
});

console.log(`Server running at http://localhost:${server.port}`);
bun build --compile ./app.ts --outfile app
./app

Build docs developers (and LLMs) love