Hey! These docs are for version 2.12, which is no longer officially supported. Click here for the latest version, 2.15!

## When to use a macro

Macros are useful to reduce boilerplate in BUILD files. For example, if you keep using the same value for a field, you can use a macro.

However, also consider that introducing new symbols to BUILD files adds some indirection to your codebase, such as making it harder to follow along with the Pants docs. As with any tool, macros should be used judiciously.

Often, you can instead use the [`parametrize`](🔗) mechanism:

If you instead want to add support for a new language, or do something more complex than a macro allows, create a new [target type](🔗).

If you are already using a target type, but need to store additional metadata for your plugin, [add a new field to the target type](🔗).

## How to add a macro

Macros are defined in Python files that act like a normal BUILD file. They have access to all the symbols you normally have registered in a BUILD file, such as all of your target types.

Macros cannot import other modules, just like BUILD files cannot have import statements.

To define a new macro, add a function with `def` and the name of the new symbol. Usually, the last line of the macro will create a new target, like this:

Then, add this file to the option `[GLOBAL].build_file_prelude_globs`:

Now, in BUILD files, you can use the new macros:

A macro can create multiple targets—although often it's better to use [`parametrize`](🔗):

A macro can perform validation:

A macro can take new parameters to generate the target dynamically. For example: