---
title: Define and replace static globals & constants
sidebarTitle: Define constants
mode: center
---

The `--define` flag declares statically-analyzable constants and globals. It replaces all usages of an identifier or property in a JavaScript or TypeScript file with a constant value, and works both at runtime and in `bun build`. It's similar to `#define` in C/C++, but for JavaScript.

```sh terminal icon="terminal"
bun --define process.env.NODE_ENV="'production'" src/index.ts # Runtime
bun build --define process.env.NODE_ENV="'production'" src/index.ts # Build
```

---

Bun uses these statically-known values for dead code elimination and other optimizations.

```ts
if (process.env.NODE_ENV === "production") {
  console.log("Production mode");
} else {
  console.log("Development mode");
}
```

---

Before the code reaches the JavaScript engine, Bun replaces `process.env.NODE_ENV` with `"production"`.

{/* prettier-ignore */}
```ts
if ("production" === "production") { // [!code ++]
  console.log("Production mode");
} else {
  console.log("Development mode");
}
```

---

Bun's optimizing transpiler also does basic constant folding.

Since `"production" === "production"` is always `true`, Bun replaces the entire expression with the `true` value and drops the unreachable `else` branch.

{/* prettier-ignore */}
```ts
if (true) { // [!code ++]
  console.log("Production mode");
}
```

---

To also collapse the surrounding `if` scaffolding down to the following output, pass `--minify-syntax` (also enabled by `--minify`):

```sh terminal icon="terminal"
bun build --define process.env.NODE_ENV="'production'" --minify-syntax src/index.ts
```

```ts
console.log("Production mode");
```

---

## What types of values are supported?

Values can be strings, identifiers, properties, or JSON.

### Replace global identifiers

To replace all usages of `window` with `undefined`:

```sh
bun --define window="undefined" src/index.ts
```

This is useful for server-side rendering (SSR), or to make sure code doesn't depend on the `window` object.

```js
if (typeof window !== "undefined") {
  console.log("Client-side code");
} else {
  console.log("Server-side code");
}
```

The value can also be another identifier. For example, to replace all usages of `global` with `globalThis`:

```sh
bun --define global="globalThis" src/index.ts
```

`global` is a global object in Node.js, but not in web browsers, so this replacement fixes code that assumes `global` is available.

### Replace values with JSON

`--define` can also replace values with JSON objects and arrays.

To replace all usages of `AWS` with the JSON object `{"ACCESS_KEY":"abc","SECRET_KEY":"def"}`:

```sh
# JSON
bun --define AWS='{"ACCESS_KEY":"abc","SECRET_KEY":"def"}' src/index.ts
```

Bun transforms these into the equivalent JavaScript code.

From:

```ts
console.log(AWS.ACCESS_KEY); // => "abc"
```

To:

```ts
console.log({ ACCESS_KEY: "abc", SECRET_KEY: "def" }.ACCESS_KEY);
```

### Replace values with other properties

You can also pass properties to the `--define` flag.

For example, to replace all usages of `console.write` with `console.log`:

```sh
bun --define console.write=console.log src/index.ts
```

That transforms the following input:

```ts
console.write("Hello, world!");
```

Into the following output:

```ts
console.log("Hello, world!");
```

## How is this different than setting a variable?

You can also set `process.env.NODE_ENV` to `"production"` in your code, but that won't help with dead code elimination. In JavaScript, property accesses can have side effects. Getters & setters can be functions, and even dynamically defined (due to prototype chains and Proxy). Even if you set `process.env.NODE_ENV` to `"production"`, static analysis tools can't assume it is still `"production"` on the next line.

## How is this different than find-and-replace or string replacement?

The `--define` flag operates on the AST (Abstract Syntax Tree), not on text. The replacement happens during transpilation, so it participates in optimizations like dead code elimination.

String replacement tools tend to have escaping issues and replace unintended parts of the code.
