3.5.4 Aspect CLI Extensibility
extraVanilla Bazel deliberately concentrates on the build graph. Repositories still need repeatable commands for formatting, linting, BUILD-file generation, delivery, and CI reporting. Aspect CLI (aspect-build/aspect-cli) is a programmable task runner on top of Bazel that gives those workflows one command surface without replacing the bazel executable.1
Install and pin it
Install the open-source CLI on macOS or Linux with the upstream installer:1
curl -fsSL https://install.aspect.build | bash
aspect help
The executable is named aspect and works alongside bazel. Check in .aspect/version.axl to pin the repository's CLI version. The launcher fetches that version on first use, keeping laptops and CI aligned.1 Treat the pin like .bazelversion: review upgrades, land the version change, then let each environment resolve the checked-in choice.
For a concrete route through the current implementation, the Aspect CLI
repository map starts at the supported README contract,
then narrows to focused AXL fixtures such as
examples/cache-diff/.
That example demonstrates an execution-log-driven task. It does not require
every AXL task to consume execution logs.2
Three built-in tasks work in any Bazel workspace without additional graph wiring:1
aspect build //...
aspect test //...
aspect run //app
aspect help lists both built-in and repository-defined tasks. Other built-ins, including format, lint, gazelle, and delivery, need repository setup: a pinned tool in MODULE.bazel, a BUILD target or rule that exposes it, and AXL configuration in .aspect/config.axl.1 Installing the CLI alone does not make aspect lint know which linters your graph uses.
Extend it with AXL
The current extension model is AXL, the Aspect Extension Language. Built-in tasks are configured in .aspect/config.axl. A custom .aspect/*.axl file becomes a project command. A small task can call Bazel and return its exit code:1
# .aspect/codegen.axl
def _impl(ctx: TaskContext) -> int:
return ctx.bazel.build(*ctx.args.targets).wait().code
codegen = task(
summary = "Run the code generator.",
implementation = _impl,
args = {
"targets": args.positional(default = ["//gen/..."]),
},
)
The checked-in task is then available locally and in CI:
aspect codegen //gen/services/...
AXL tasks can run subprocesses, read or update repository files, query the graph, and subscribe to the Build Event Stream or compact execution log.1 3.7.3 Aspect Extension Language (AXL) develops that orchestration model. The decision here is whether the repository benefits from adopting Aspect CLI as its shared task surface.
Keep the launcher layers distinct
- Bazelisk (0.1.1 Bazelisk & .bazelversion) selects and downloads the Bazel version named by the repository.
tools/bazel(3.2.8 tools/bazel Wrapper) is a thin pre-Bazel setup hook for environment stabilization and policy.- Aspect CLI runs project tasks around Bazel and is invoked as
aspect. - AXL (3.7.3 Aspect Extension Language (AXL)) is the language used to configure and author those tasks.
This separation makes adoption reversible. Existing bazel build and bazel test commands remain valid, while selected human and CI workflows move to aspect <task> when its reporting, retries, or orchestration justify the additional tool.
Aspect CLI versions 2025.41 and earlier used a different Go implementation. They commonly shadowed bazel through Homebrew or .bazeliskrc, extended the CLI through a gRPC plugin protocol, and bundled Gazelle under configure. Version 2025.42 introduced the Rust rewrite: aspect now sits alongside bazel, AXL replaces the gRPC plugin system, and the precompiled Gazelle integration moved to the standalone aspect-gazelle project.1 Do not copy the old .bazeliskrc, CustomCommands, BEPEventCallback, or PostBuildHook recipes into a current setup.
To see what aspect init currently materializes, use the
aspect-workflows-template map. The
template/.aspect/
directory is the delivered project configuration, while
render.axl
belongs to the template generator itself. Keeping those apart prevents a common
mistake: editing the meta-template workflow when the task is only to maintain a
generated workspace.
Aspect CLI is a standalone, programmable task runner on top of Bazel. Install aspect, pin it with .aspect/version.axl, use aspect build, test, and run immediately, and wire tool-backed tasks such as lint or gazelle into both the Bazel graph and .aspect/config.axl. Current customization uses AXL in .aspect/*.axl. .bazeliskrc shadowing and gRPC plugins describe the legacy CLI, not the current product.
Check your understanding · 3 questions
1.What is the smallest current setup that keeps Aspect CLI consistent across developer machines and CI?
Select one answer
2.Match each repository file or command to its current role:
Drag each answer onto the matching prompt, or click an answer and then click a prompt
3.True or false about current Aspect CLI behavior:
Choose True or False for each sentence
.bazeliskrc shadowing and gRPC plugin hooks describe versions 2025.41 and earlier.Footnotes
-
Aspect CLI upstream README — current installation, version pinning, built-in and custom tasks, AXL configuration, CI use, and the explicit comparison with versions 2025.41 and earlier ↩1 ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
Aspect CLI repository map — routes from the public CLI/AXL contract to focused examples and implementation packages ↩