--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.
terminal
Bun uses these statically-known values for dead code elimination and other optimizations.
Before the code reaches the JavaScript engine, Bun replaces
process.env.NODE_ENV with "production".
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.
To also collapse the surrounding
if scaffolding down to the following output, pass --minify-syntax (also enabled by --minify):
terminal
What types of values are supported?
Values can be strings, identifiers, properties, or JSON.Replace global identifiers
To replace all usages ofwindow with undefined:
window object.
global with globalThis:
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"}:
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:
How is this different than setting a variable?
You can also setprocess.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.