# use-macro

> ESBuild plugin that allows you to execute functions at compile time and inline the output

Latest version **1.1.0** (published 2025-01-14) · MIT license · 0 weekly downloads

## Install

```sh
npm install use-macro
pnpm add use-macro
yarn add use-macro
bun add use-macro
```

## Health

**Score 55/100 (C)** — status: stable.

Positive: has types; esm support; no vulnerabilities; high maintenance score; high quality score.

Warnings: low downloads.

Negative: stale.

## Facts

| | |
|---|---|
| Version | 1.1.0 |
| Published | 2025-01-14 |
| First published | 2024-12-25 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 8 |
| Unpacked size | 29.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 10 |
| Author | Twilight |
| Maintainers | snowflake7 |
| Keywords | macro, esbuild, compile-time, plugin |

## Links

- npm: https://www.npmjs.com/package/use-macro
- Repository: https://github.com/twlite/use-macro
- Homepage: https://github.com/twlite/use-macro#readme
- Issues: https://github.com/twlite/use-macro/issues
- npm.io page: https://npm.io/package/use-macro

## Dependencies (8)

- [devalue](https://npm.io/package/devalue.md) ^5.1.1
- [@babel/core](https://npm.io/package/@babel/core.md) ^7.26.0
- [@babel/types](https://npm.io/package/@babel/types.md) ^7.26.3
- [@babel/parser](https://npm.io/package/@babel/parser.md) ^7.26.3
- [@babel/traverse](https://npm.io/package/@babel/traverse.md) ^7.26.4
- [@babel/generator](https://npm.io/package/@babel/generator.md) ^7.26.3
- [@types/babel__core](https://npm.io/package/@types/babel__core.md) ^7.20.5
- [@babel/preset-typescript](https://npm.io/package/@babel/preset-typescript.md) ^7.26.0

## Alternatives

- [raw-loader](https://npm.io/package/raw-loader.md) — 4.3M weekly downloads
- [plop](https://npm.io/package/plop.md) — 1.4M weekly downloads
- [webpack-deadcode-plugin](https://npm.io/package/webpack-deadcode-plugin.md) — 80.3K weekly downloads
- [@storybook/preact-vite](https://npm.io/package/@storybook/preact-vite.md) — 54.2K weekly downloads
- [vite-plugin-transform](https://npm.io/package/vite-plugin-transform.md) — 2.4K weekly downloads

## Recent versions

- 1.1.0 (latest) — 2025-01-14
- 2.0.0-next.1 (next) — 2026-10-11
- 2.0.0-next.0 — 2026-10-11
- 1.0.1 — 2024-12-25
- 1.0.0 — 2024-12-25

## README

# ESBuild Plugin Use Macro

This is a plugin for [esbuild](https://esbuild.github.io/) that allows you to use macros in your code. Macros are a way to define a function that will be executed at compile time, and will replace the macro call with the result of the function.

> Note: This package is esm only.

## Features

- [x] Macros are defined as regular functions that are marked with the `use macro` directive.
- [x] Macro functions can be async.
- [x] Macro functions are automatically awaited.
- [x] Supports serialization of various types like primitive types, Map, Set, Date, RegExp, and Request, Response, FormData, URL, URLSearchParams, and more.
- [x] Macro functions are self contained, they cannot access the scope of the calling code.

## Installation

```bash
npm install use-macro
```

## Usage

### Lets create a simple macro that will extract the version from the package.json file

<!-- prettier-ignore -->
```typescript
function $version(): string {
  'use macro';
  const { version } = require('../package.json');
  console.log(`Version: ${version}`);

  return version;
}

function $compiledAt(): Date {
  'use macro';
  return new Date();
}

async function $message(): Promise<string> {
  'use macro';

  const fs = require('fs').promises;
  const path = require('path');
  const messageText = path.resolve(__dirname, 'message.txt');
  const res = await fs.readFile(messageText, 'utf8');

  return res;
}

const $url = () => {
  'use macro';
  const url = new URL('https://example.com?foo=bar&baz=qux');

  return [url, url.searchParams];
};

const $formData = function () {
  'use macro';
  const formData = new FormData();
  formData.append('foo', 'bar');
  formData.append('baz', 'qux');

  return formData;
};

export const version = $version();
export const compiledAt = $compiledAt();
export const message = $message() as unknown as Awaited<ReturnType<typeof $message>>;
export const url = $url();
export const formData = $formData();
```

### Now lets register the macro in the esbuild plugin

```typescript
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));
```

> Note: You can also use this plugin with [tsup](https://tsup.egoist.sh/) by passing the `esbuildOptions` object to the `tsup` function.

### Now lets run the build. The output will be:

<!-- prettier-ignore -->
```javascript
// src/index.ts
var version = (
  /* @__MACRO__ $version */
  "1.0.0"
);
var compiledAt = (
  /* @__MACRO__ $compiledAt */
  /* @__PURE__ */ new Date(1736839318808)
);
var message = (
  /* @__MACRO__ $message */
  "Hello World!"
);
var url = (
  /* @__MACRO__ $url */
  [new URL("https://example.com/?foo=bar&baz=qux"), new URLSearchParams([["foo", "bar"], ["baz", "qux"]])]
);
var formData = (
  /* @__MACRO__ $formData */
  new FormData([["foo", "bar"], ["baz", "qux"]])
);
export {
  compiledAt,
  formData,
  message,
  url,
  version
};
```

Notice how entire function was removed and the function call was replaced with the result of the function.

## Transformer API (Usage without esbuild)

`use-macro` can be used without esbuild as a standalone transformer. This can be useful if you want to use macros in other tools programmatically.

```typescript
import { MacroTransformer } from 'use-macro';

const transformer = new MacroTransformer();

const code = `
function $random(): number {
  'use macro';
  return Math.random();
}
`;

/**
 * The first argument is the code to transform.
 * The second argument is the file name, this is used to resolve relative imports.
 */
const result = transformer.transform(code, 'file.ts');

/*
{
  content: '...',
  loader: 'ts'
}
*/
```

---
_Source: https://npm.io/package/use-macro · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
