bun build ./index.ts --outdir ./out: bundle with Bun
- tool
- Bun
- versions
- Bun 1.x
- os
- any
bun build ./index.ts --outdir ./out bundles the entry file and everything it imports into out/index.js, stripping TypeScript types and resolving node_modules. The default target is the browser; add --target bun or --target node for server code, --minify for production, and --compile to produce a single native executable that includes the Bun runtime.
Example
cat > greet.ts <<'EOF'
export const greet = (name: string): string => `hello ${name}`;
EOF
cat > index.ts <<'EOF'
import { greet } from "./greet";
console.log(greet("bun"));
EOF
npx --yes bun@1 build ./index.ts --outdir ./out > /dev/null 2>&1
echo "--- out/index.js"
cat out/index.js
npx --yes bun@1 build ./index.ts --outdir ./min --minify > /dev/null 2>&1
echo "--- min/index.js"
cat min/index.js
echo
node out/index.jsOutput
--- out/index.js
// greet.ts
var greet = (name) => `hello ${name}`;
// index.ts
console.log(greet("bun"));
--- min/index.js
var o=(e)=>`hello ${e}`;console.log(o("bun"));
hello bunBoth modules end up in one file, and the type annotations are gone, so the output runs in Node.js or a browser.
Types are stripped, not checked
cat > bad.ts <<'EOF'
const n: number = "not a number";
console.log(n);
EOF
npx --yes bun@1 build ./bad.ts --outfile bad.js --target node > /dev/null 2>&1
echo "build exit=$?"
cat bad.jsOutput
build exit=0 // bad.ts var n = "not a number"; console.log(n);
The build succeeds although the code assigns a string to a number. Like esbuild and other fast bundlers, Bun transpiles TypeScript without running the type checker. Add --check to type-check the entry points and everything they import (nothing is bundled if there are type errors), or keep tsc --noEmit as a separate CI step.
Main options
| Option | Effect |
|---|---|
| --outdir DIR | Write output files to DIR (required with several entry points) |
| --outfile FILE | Write a single output file |
| --target browser|bun|node | Environment the bundle runs in (default browser) |
| --format esm|cjs|iife | Module format of the output (default esm) |
| --minify | Minify whitespace, identifiers and syntax |
| --sourcemap=linked|inline|external | Emit a source map |
| --splitting | Share code between entry points in chunks |
| --external PKG | Leave an import unbundled (repeatable) |
| --compile | Build a standalone executable with --outfile |
| --packages external | Do not bundle anything from node_modules |
| --watch | Rebuild when a source file changes |
| --define KEY=VALUE | Replace a global identifier with a constant at build time |
| --env inline | Replace process.env.NAME with the current values (or --env PREFIX_* for a subset) |
Choosing a target
| --target | Resolution and output |
|---|---|
| browser (default) | Prefers the browser export condition; node:path and similar imports work, but calls such as fs.readFile do not |
| bun | For code that runs in Bun; adds a // @bun pragma so Bun skips re-transpiling. Default when the entry has a #!/usr/bin/env bun shebang |
| node | Prefers the node export condition and emits code for Node.js |
A server bundle built with the default browser target can pick up browser builds of dependencies or fail at run time on Node.js APIs, so set the target explicitly for anything that does not run in a browser.
Standalone executable
bun build ./cli.ts --compile --outfile mycli
./mycliThe executable embeds the Bun runtime, so it is tens of megabytes and runs on machines without Bun. Use --target=bun-linux-x64, bun-darwin-arm64 or bun-windows-x64 to cross-compile for another platform.
FAQ
Does bun build check TypeScript types?
Not by default: it removes type annotations and bundles the code even when it has type errors. Recent Bun versions add --check, which type-checks the entry points and bundles nothing if there are errors. bun build never generates .d.ts declaration files; use tsc for those.
Do I need bun build to run a TypeScript server with Bun?
No. bun index.ts runs the source directly. Bundling with --target bun is optional and mainly reduces startup time or produces a single file to deploy.
How do I keep node_modules out of the bundle?
Pass --packages external to leave every package import unbundled, or --external PKG for specific ones. The output then needs those packages installed where it runs.