record() and enum() among them. You’ll see all three as the course goes on.
Install
See How to install the Aspect CLI for every option, or run:sudo mv into /usr/local/bin, so you need admin rights on the machine.
On macOS, Homebrew works too:
What you just installed
PATH is a small program whose only job is to fetch and run the right Aspect CLI for whatever repository you happen to be standing in.
Two commands that differ only by a -- report two different programs:
The launcher version and the CLI version do not have to match. Stand in two repositories with different pins —
.aspect/version.axl, which the next section is about — and they come apart:
2026.41.28, the pin-b lines arrive behind a downloading aspect cli version v2026.41.28 / downloaded … pair — the shape shown in the next section. That is the launcher doing its job, once per version.
One launcher, two CLIs, and the launcher line never moved. That is the design: the launcher is to the Aspect CLI what Bazelisk is to Bazel, so every developer on your team runs the same CLI version without anyone coordinating, because the repository decides.
The launcher itself rarely changes, and its own version almost never matters — the version that matters is the one it fetches for you. To upgrade it, run the install line again or
brew upgrade aspect. The Homebrew formula is generally updated only when the launcher changes, so it can report an older version than curl installs.Pinning a version
A repository pins its CLI version in.aspect/version.axl. You can also put one in your home directory, at ~/.aspect/version.axl, as a personal default.
When both exist, the repository wins — a repository has real commitments to a version (its config.axl, its tasks, its CI), while the home pin is just your fallback for repositories that haven’t expressed an opinion.
Unpinned, the launcher fetches the latest release. Run this somewhere with no pin:
A little housekeeping
Before the first exercise, here is something useful the CLI will do for you right now. Deleting a git worktree leaves its Bazel output base behind. Nothing in Bazel collects it, so every branch you have ever checked out and thrown away is probably still on this laptop — and if you run coding agents, which make a worktree per task, there will be more of them than you expect. This is read-only and takes a second:aspect gc to remove what nothing is using, and aspect worktree to stop the orphans accumulating in the first place. Worth running before you create one more output base, which the next section is about to do.
Those three are AXL tasks, like the ones you are about to write. None of them changes how a build works — they improve the work around it, and they do it in the same Starlark you already use for Bazel.
Next: a project consisting of exactly one file.
