Skip to main content
Bun includes a fast JavaScript and TypeScript minifier that can reduce bundle sizes by 80% or more. It performs constant folding, dead code elimination, syntax transformations, and identifier shortening. Because Bun minifies during bundling (not as a separate pass), there is less code to print — making bun build faster than running an external minifier.

Enabling minification

Use --minify to enable all minification modes at once:
bun build ./index.ts --outdir ./out --minify
--minify enables all three modes: whitespace removal, syntax optimization, and identifier shortening.

Production mode

The --production flag also enables full minification:
bun build ./index.ts --outdir ./out --production
--production additionally sets process.env.NODE_ENV to "production" and enables the production JSX transform.

Granular control

Enable individual modes separately:
# Whitespace only
bun build ./index.ts --outdir ./out --minify-whitespace

# Syntax only
bun build ./index.ts --outdir ./out --minify-syntax

# Identifiers only
bun build ./index.ts --outdir ./out --minify-identifiers

# Combine specific modes
bun build ./index.ts --outdir ./out --minify-whitespace --minify-syntax

Minification modes

--minify-whitespace

Removes all unnecessary whitespace, newlines, comments, and formatting.
function add(a: number, b: number) {
    // Add two numbers
    return a + b;
}

const result = add(1, 2);
License comments (/*! ... */) are preserved.

--minify-syntax

Rewrites JavaScript syntax to shorter equivalent forms. Performs constant folding, dead code elimination, and dozens of other optimizations.
// Constant folding
const x = 1 + 2;
const s = "foo" + "bar";
const t = `hello ${123}`;

// Dead code elimination
if (false) {
  unreachable();
}

// Boolean shortening
const a = true;
const b = false;

// Logical folding
const c = true && getValue();
const d = false || getDefault();

--minify-identifiers

Renames local variables and function names to shorter identifiers using frequency-based optimization. The most-used identifiers get the shortest names.
function calculateSum(firstNumber: number, secondNumber: number) {
  const result = firstNumber + secondNumber;
  return result;
}
Named exports, exports, module, JavaScript keywords, and global identifiers are never renamed.

Combined example

Using all three modes together:
const myVariable = 42;

const myFunction = () => {
  const isValid = true;
  const result = undefined;
  return isValid ? myVariable : result;
};

const output = myFunction();

Syntax transformations reference

// Input
true;   false;
!!x;    x === true;    x && true;    x || false;

// Output
!0;     !1;
x;      x;             x;            x;
// Input
1 + 2;   10 - 5;   3 * 4;   10 / 2;   2 ** 3;

// Output
3;       5;        12;      5;        8;
// Input
"foo" + "bar";   "hello " + "world";   `result: ${5 + 10}`;

// Output
"foobarbaz";     "hello world";         "result: 15";
// Input
if (false) { unreachable(); }
while (false) { neverRuns(); }
function foo() { return x; deadCode(); }

// Output
function foo() { return x; }
// Input
undefined;   Infinity;   -Infinity;

// Output
void 0;      1/0;        -1/0;
// Input
typeof x === 'undefined';
typeof require;
typeof null;
typeof true;

// Output
typeof x > 'u';
"function";
"object";
"boolean";
// Input
10000;   100000;   1.0;   -42.0;

// Output
1e4;     1e5;      1;     -42;
// Input
enum Color { Red, Green, Blue }
const x = Color.Red;

// Output (enum is eliminated)
const x = 0;
// Input
let a = 1;
let b = 2;
const c = 3;
const d = 4;

// Output
let a=1,b=2;
const c=3,d=4;
// Input
if (true) x;
if (false) x;
if (x) {} else y;

// Output
x;
// removed
if (!x) y;

Source maps with minification

Always use source maps in production so that error stack traces point to original source:
bun build ./index.ts --outdir ./out --minify --sourcemap=linked
See Bundler Overview — sourcemaps for all sourcemap options.

Bytecode compilation

Combine minification with --bytecode to also reduce startup time:
bun build ./index.ts --outdir ./out --minify --sourcemap --bytecode --target=bun
Bytecode pre-compiles JavaScript to JavaScriptCore bytecode at build time, moving parsing overhead out of the critical startup path. Typical improvement: 1.5–4x faster startup depending on application size. Bytecode caching generates a .jsc file alongside each .js bundle. Bun automatically uses it at runtime:
ls dist/
# index.js   (245 KB)
# index.jsc  (1.1 MB)

bun ./dist/index.js  # uses index.jsc automatically
Bytecode is not portable across Bun versions. The .jsc file is tied to the JavaScriptCore version embedded in the Bun binary. Regenerate bytecode after updating Bun.

Keep names

When minifying identifiers, preserve original function and class names for better stack traces:
bun build ./index.ts --outdir ./out --minify --keep-names
This preserves the .name property on functions and classes while still shortening identifier names in the code.

Drop specific calls

Remove console.* calls or debugger statements from production builds:
bun build ./index.ts --outdir ./out --drop=console --drop=debugger
You can also drop custom function calls by name:
bun build ./index.ts --outdir ./out --drop=assert

When to use each mode

--minify-whitespace

Quick size reduction without any semantic changes. Safe to use on its own without full syntax minification.

--minify-syntax

Smaller output while keeping readable identifier names. Good for debugging production issues.

--minify-identifiers

Maximum compression. Combine with --keep-names for better stack traces.
For production CLI tools and long-running servers, use --minify --sourcemap=linked --bytecode together for the best combination of small output and fast startup.
Avoid minification for development builds — it makes errors harder to debug and provides no benefit during development.

Build docs developers (and LLMs) love