Skip to main content
After installing the Aspect CLI, run aspect help to view the list of available tasks. For example:
% aspect help
Aspect's programmable task runner built on top of Bazel
{ Correct, Fast, Usable } -- Choose three

Usage: aspect <TASK>

Tasks:
  build    build task defined in @aspect//build.axl
  test     test task defined in @aspect//test.axl
  axl      axl task group
  version  Print version
  help     Print this message or the help of the given subcommand(s)

Options:
  -v, --version  Print version
  -h, --help     Print help
Some tasks are built-in, while others are downloaded on demand.

Extension Discovery

The Aspect CLI discovers extensions in the following locations:
  • .aspect/*.axl
It begins searching for .aspect directories from your current working directory, traversing upward to the root of your Bazel workspace. This enables teams to scope tasks to specific subdirectories rather than applying them project-wide. Each .aspect directory contains .axl files defining the extension code. Additionally, you can include a MODULE.aspect file in your repository to specify external sources for extensions. For example:
.
├── .aspect/
│   ├── build.axl
│   └── mycmd.axl # defines a 'mycmd' task
├── app1/
│   └── .aspect/
│       └── subcmd.axl # defines a 'subcmd' task that only appears when the working directory is within 'app1'
├── MODULE.aspect
└── MODULE.bazel
When you cd app1 and then run aspect, the Aspect CLI first loads tasks from ./app1/.aspect/*.axl, then traverses up the tree to the topmost directory of your Bazel project and discovers all available tasks it finds in .aspect/*.axl at each point. As a result, the ‘build’ and ‘mycmd’ tasks come from the repository root, while the ‘subcmd’ task comes from the app1 folder.

Write your first extension

Extensions are written in the Aspect Extension Language (AXL) to define tasks and create custom workflows suited to your project’s requirements. Follow these steps to create a custom mycmd task that wraps Bazel’s build functionality:
  1. Create a .aspect directory at the root of your project:
    mkdir .aspect
    
  2. Create a file named mycmd.axl within the .aspect directory:
    touch .aspect/mycmd.axl
    
  3. Add the following Starlark code to mycmd.axl:
    def impl(ctx: TaskContext) -> int:
        build = ctx.bazel.build(
            events = True,
            inherit_stderr = False,
            *ctx.args.target_pattern,
        )
    
        for event in build.build_events():
            if event.kind == "named_set_of_files":
                for file in event.payload.files:
                    ctx.std.io.stdout.write("Built {}\n".format(file.file))
    
        build_status = build.wait()
        return build_status.code
    
    mycmd = task(
        implementation = impl,
        args = {
            "target_pattern": args.positional(default = ["..."]),
        }
    )
    
  4. Verify the new task appears:
    % aspect help
    Usage: aspect <TASK>
    
    Tasks:
      mycmd      mycmd task defined in .aspect/mycmd.axl
      ...
      help       Print this message or the help of the given subcommand(s)
    
  5. Test the new AXL task by running:
    aspect mycmd //...
    
This task builds all targets and lists the output files reported by Bazel.