skills/bun-guides-runtime-define-constant/SKILL.md
Define and replace static globals & constants
npx skillsauth add jarle/bun-skills Bun Define and replace static globals & constantsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
The --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.
bun --define process.env.NODE_ENV="'production'" src/index.ts # Runtime
bun build --define process.env.NODE_ENV="'production'" src/index.ts # Build
These statically-known values are used by Bun for dead code elimination and other optimizations.
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".
if ("production" === "production") { // [!code ++]
console.log("Production mode");
} else {
console.log("Development mode");
}
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.
if (true) { // [!code ++]
console.log("Production mode");
} else {
console.log("Development mode");
}
And finally, Bun detects the else branch is not reachable, and eliminates it.
console.log("Production mode");
Values can be strings, identifiers, properties, or JSON.
To make all usages of window be undefined, you can use the following command.
bun --define window="undefined" src/index.ts
This can be useful when Server-Side Rendering (SSR) or when you want to make sure that the code doesn't depend on the window object.
if (typeof window !== "undefined") {
console.log("Client-side code");
} else {
console.log("Server-side code");
}
You can also set the value to be another identifier. For example, to make all usages of global be globalThis, you can use the following command.
bun --define global="globalThis" src/index.ts
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.
--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.
# JSON
bun --define AWS='{"ACCESS_KEY":"abc","SECRET_KEY":"def"}' src/index.ts
Those will be transformed into the equivalent JavaScript code.
From:
console.log(AWS.ACCESS_KEY); // => "abc"
To:
console.log("abc");
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
bun --define console.write=console.log src/index.ts
That transforms the following input:
console.write("Hello, world!");
Into the following output:
console.log("Hello, world!");
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", on the next line, it is not safe for static analysis tools to assume that process.env.NODE_ENVis"production".
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.
development
Using TypeScript with Bun, including type definitions and compiler options
development
Learn how to write tests using Bun's Jest-compatible API with support for async tests, timeouts, and various test modifiers
testing
Learn how to use snapshot testing in Bun to save and compare output between test runs
testing
Learn about Bun test's runtime integration, environment variables, timeouts, and error handling