> ## Documentation Index
> Fetch the complete documentation index at: https://site.aspect.build/llms.txt
> Use this file to discover all available pages before exploring further.

# AXL, the Aspect Extension Language

> Configure the Aspect CLI, write custom tasks, extend BUILD file generation and subscribe to build events in a Starlark dialect Bazel users already know.

AXL is a [Starlark](https://starlark-lang.org/) dialect for programming the Aspect CLI. You configure the built-in tasks with it, write your own, generate BUILD files, and read Bazel's build events as they arrive, in a language your team already reads in `.bzl` files.

## Why Starlark

Bazel users already know it. Functions, `load` statements, deterministic evaluation, no I/O at analysis time: the mental model transfers directly from `.bzl` files, so the language isn't the thing you have to learn.

Configuration can branch on the CI host, the platform, or whether a deployment is reachable, without a templating language or the non-determinism of a general-purpose one.

AXL draws on [Buck's BXL](https://buck2.build/docs/bxl/) and [Tilt](https://docs.tilt.dev/api.html), which use Starlark for the same purpose.

## What you can do with it

<CardGroup cols={2}>
  <Card title="Configure the built-in tasks" icon="sliders" href="/docs/cli/guides/basic">
    Set defaults per repository in <code>.aspect/config.axl</code> (which formatter runs, which targets a task defaults to, which flags it passes) so nobody has to remember them at the command line.
  </Card>

  <Card title="Write custom tasks" icon="code" href="/docs/cli/guides/basic#how-tasks-are-registered">
    Register a Starlark function with <code>task()</code> and it becomes a real CLI command, with its own flags, help text and status checks.
  </Card>

  <Card title="Generate BUILD files" icon="cubes" href="/docs/cli/guides/gazelle">
    Write a Gazelle extension in Starlark rather than in Go, so the people who own a language's conventions can own its BUILD generation.
  </Card>

  <Card title="Subscribe to build events" icon="rss" href="/docs/cli/guides/build-events">
    Read Bazel's Build Event Protocol stream as it arrives and act on it: collect outputs, detect flakes, feed your own systems.
  </Card>
</CardGroup>

## What it looks like

Configuration is a function the CLI calls with a context:

```python title=".aspect/config.axl" theme={null}
load("@aspect//format.axl", "format")

buildifier = format.alias(
    defaults = {
        "formatter_target": "@buildifier_prebuilt//buildifier",
        "formatter_args_for_tree_walk": ["-r", "."],
        "run_in": "cwd",
        "include_patterns": [
            "**/BUILD",
            "**/BUILD.bazel",
            "**/MODULE.bazel",
            "**/*.MODULE.bazel",
            "**/WORKSPACE",
            "**/WORKSPACE.bazel",
            "**/*.axl",
            "**/*.bzl",
        ],
    },
)

def config(ctx: ConfigContext):
    ctx.tasks.add(buildifier)
    ctx.tasks["setup/bazelrc"].args.omit_bazel_flags = ["--heap_dump_on_oom"]
```

A custom task is a function plus a `task()` registration. Drop it in any `.axl` file under `.aspect/` and it is discovered as a command:

```python title=".aspect/build-and-list.axl" theme={null}
def _impl(ctx: TaskContext) -> int:
    events = bazel.build_events.iterator(kinds = ["named_set_of_files"])
    build = ctx.bazel.build(*ctx.args.targets, build_events = [events])

    for event in events:
        for f in event.payload.files:
            ctx.std.io.stdout.write("Built {}\n".format(f.name))

    return build.wait().code

build_and_list = task(
    summary = "Build targets and list every output file.",
    implementation = _impl,
    args = {"targets": args.positional(default = ["..."], maximum = 512)},
)
```

`aspect build-and-list` is now a command alongside the built-ins. Underscores in the variable name become dashes.

## Where to start

* **[The basics](/docs/cli/guides/basic)**: `config.axl`, how tasks are registered, and the file precedence rules.
* **[Write your first custom task](/quickstart#write-your-first-custom-task)**: the quickstart's worked example.
* **[Task hooks](/docs/cli/guides/task-hooks)**: run code around a task without replacing it.
* **[AXL reference](/docs/axl/types)**: every type and built-in, generated from the source.

## The talk

The BazelCon 2025 talk on AXL covers the language and the design decisions behind it:

<iframe className="w-full aspect-video rounded-xl" src="https://www.youtube.com/embed/j7-IMZ2q5W4" title="AXL at BazelCon 2025" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowFullScreen />

## Community

**[Join the Aspect Community Slack](https://slack.aspect.build)**, Aspect's free community support. Ask in `#help` for general support. Join the discussion and see what others are building with the [Aspect CLI](/docs/cli/overview) and [Aspect Extension Language (AXL)](/docs/cli/axl) in the `#cli` and `#axl` channels.

For Bazel and the Bazel rulesets, [Bazel Slack](https://slack.bazel.build) is the best place for support and discussion. Ask about Aspect's [rules\_js](/docs/bazel/javascript) in `#javascript` and [rules\_py](/docs/bazel/python) in `#python`.
