Bun Macros: with { type: 'macro' } Build-Time Code Evaluation
- Last updated
- Prerequisites:
- ES Module imports
- Compile-time code generation / Babel plugins
- bun
- macros
- compile-time
- metaprogramming
- ast
- inlining
Read at your depth
The practical view
Bun Macros let you run JavaScript functions at **bundle time** and inline the returned result directly into the generated bundle. Import any function with macro attribute syntax: `import { getGitCommit } from './git.ts' with { type: 'macro' };`. When you call `const commit = getGitCommit();`, Bun executes `getGitCommit()` during bundling and replaces the call with the static returned string/object.
The same idea in other frameworks
Rust procedural/declarative macros (`macro_rules!`).C preprocessor `#define` and macro expansions.Babel macros (`babel-plugin-macros`) requiring custom build plugins.`import { fn } from './macro.ts' with { type: 'macro' };`.Legacy vs modern
Runtime File Reading vs Compile-Time Bun Macro Inlining
Runtime file reading adds I/O latency to every startup; Bun Macros inline file contents directly at build time.
const gitHash = execSync('git rev-parse HEAD'); // ❌ Slow runtime shell spawnimport { getGitHash } from './macro.ts' with { type: 'macro' }; const hash = getGitHash(); // ✅ NEWInterview gotchas
Context
Interviewers test your knowledge of macro serialization boundaries.
The mechanical answer
Bun Macros can return: (1) **JSON-serializable data** (strings, numbers, booleans, arrays, objects), (2) **`Response` objects** (whose text or JSON will be inlined), (3) **`Blob` / `TypedArray`** (inlined as base64 or binary data), or (4) **AST function wrappers**.
Trap
A macro cannot return complex runtime instances like active database connection pools, live sockets, or un-serializable symbols.
Context
Checks understanding of asynchronous compile-time execution.
The mechanical answer
Yes. A macro can be an `async` function that executes `await fetch('https://api.cms.com/schema')`. Bun will await the promise during the bundling phase and inline the resolved data directly into the client bundle.
Trap
If the remote API is down during build time, the `Bun.build` compile step will fail.