--define flag lets you declare statically-analyzable constants and globals. It replace all usages of an identifier or property in a JavaScript or TypeScript file with a constant value. This feature is supported at runtime and also in bun build. This is sort of similar to #define in C/C++, except for JavaScript.
terminal
These statically-known values are used by Bun for dead code elimination and other optimizations.
Before the code reaches the JavaScript engine, Bun replaces
process.env.NODE_ENV with "production".
It doesn’t stop there. Bun’s optimizing transpiler is smart enough to do some basic constant folding. Since
"production" === "production" is always true, Bun replaces the entire expression with the true value.
And finally, Bun detects the
else branch is not reachable, and eliminates it.
What types of values are supported?
Values can be strings, identifiers, properties, or JSON.Replace global identifiers
To make all usages ofwindow be undefined, you can use the following command.
window object.
global be globalThis, you can use the following command.
global is a global object in Node.js, but not in web browsers. So, you can use this to fix some cases where the code assumes that global is available.
Replace values with JSON
--define can also be used to replace values with JSON objects and arrays.
To replace all usages of AWS with the JSON object {"ACCESS_KEY":"abc","SECRET_KEY":"def"}, you can use the following command.
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, you can use the following command (requires Bun v1.1.5 or later)
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", on the next line, it is not safe for static analysis tools to assume that process.env.NODE_ENVis"production".
How is this different than find-and-replace or string replacement?
The--define flag operates on the AST (Abstract Syntax Tree) level, not on the text level. It happens during the transpilation process, which means it can be used in optimizations like dead code elimination.
String replacement tools tend to have escaping issues and replace unintended parts of the code.