use-macro

raw JSON →
1.1.0 verified Fri May 01 auth: no javascript

ESBuild plugin (v1.1.0, active development) that executes TypeScript/JavaScript functions at compile time and replaces their calls with the computed result, enabling compile-time code generation and optimization. Differentiates from Babel macros by being esbuild-native and ESM-only, supporting async macros, and serializing complex types like Map, Set, Date, RegExp, and web API objects. Released on npm, with TypeScript type declarations included.

error Error [ERR_REQUIRE_ESM]: require() of ES Module not supported.
cause Using require() to import 'use-macro', which is ESM-only.
fix
Use import statement instead: import { esbuildPluginUseMacro } from 'use-macro'
error TypeError: esbuildPluginUseMacro is not a function
cause Attempting to use an incorrectly imported value, possibly the default export which does not exist.
fix
Use named import: import { esbuildPluginUseMacro } from 'use-macro' and then call it: esbuildPluginUseMacro(options)
error ReferenceError: require is not defined (or module is not defined) inside macro function
cause Using require in a JavaScript/ESM environment without bundling; but for macros, require is allowed if the bundler (esbuild) provides it.
fix
Ensure esbuild is set to bundle the code. If using tsup, enable esbuild bundling. For standalone transformer, provide a custom module resolution.
breaking The package is ESM-only and does not support CommonJS require() or Node's --experimental-require-module.
fix Use ESM imports ('import' instead of 'require') and ensure project is configured for ESM (e.g., type: 'module' in package.json or .mjs extension).
gotcha Macro functions must include 'use macro' directive; otherwise they execute at runtime and import/require inside them may fail at build time.
fix Add 'use macro'; as the first statement in any function intended as a macro. The directive is a string literal, not a pragma comment.
gotcha Macro functions are isolated and cannot access outer scope variables; any dependency must be imported or required inside the macro body.
fix Move all required imports inside the macro function. The macro cannot reference variables from the enclosing module scope.
deprecated Version 1.0.0 had a bug where async macros were not correctly awaited in some edge cases; fixed in 1.1.0.
fix Update to version 1.1.0 or later.
npm install use-macro
yarn add use-macro
pnpm add use-macro

Basic esbuild integration: registers the plugin and uses a macro to inline a compile-time Date.

import { build } from 'esbuild';
import { esbuildPluginUseMacro } from 'use-macro';

build({
  entryPoints: ['src/index.ts'],
  bundle: true,
  outfile: 'dist/index.js',
  plugins: [esbuildPluginUseMacro()],
}).catch(() => process.exit(1));

// In src/index.ts:
function $compiledAt(): Date {
  'use macro';
  return new Date();
}
export const compiledAt = $compiledAt();