aspect binary you install is a thin launcher — it provisions and execs the real aspect-cli for your project. The launcher decides which CLI version to run by reading a single file in your repository:
aspect-cli, regardless of how recently they installed the launcher.
Pin a version
Create.aspect/version.axl at your repository root, alongside MODULE.bazel (or MODULE.aspect):
v2026.27.7 directly from the Aspect CLI GitHub Releases the first time it’s needed and caches the binary locally. If the download fails, the launcher reports an error — a pinned version never silently falls back to a different release.
No project version.axl
If the launcher can’t find a .aspect/version.axl in any parent directory of the working directory (i.e. there is no project root pinning a version), it resolves the version in this order:
- User-level pin —
~/.aspect/version.axl. As of Aspect CLI 2026.27.7, the launcher falls back to aversion.axlin your home directory. This file uses the same syntax as a project-level pin and lets you set a default CLI version for work outside any pinned project, without touching a repository. - Floating mode — if no user-level file exists either, the launcher queries the GitHub releases API for the most recent non-prerelease and downloads that. The resolved tag is cached for 24 hours so subsequent runs do not hit the API.
A project-level
.aspect/version.axl always wins. The ~/.aspect/version.axl fallback only applies when no project root is found, so it never overrides a version a repository has pinned.aspect-cli version. Pin a version — per project, or per user via ~/.aspect/version.axl — for any project where reproducibility matters.
Custom sources
The optionalsources list overrides where the launcher looks for the CLI binary. Sources are tried in order; the first one that succeeds wins.
sources is omitted, it defaults to [github(org = "aspect-build", repo = "aspect-cli")].
local(path)
Use a binary at a path relative to the repository root. Useful when developing the CLI locally:
github(org, repo, tag?, artifact?)
Download from a GitHub release:
tag and artifact are omitted the launcher derives defaults:
tagdefaults tov{version}(e.g.v2026.27.7)artifactdefaults to{repo}-{target}(e.g.aspect-cli-aarch64-apple-darwin)
http(url, headers?)
Download from an arbitrary URL — for example, an internal mirror:
Template variables
tag, artifact, and url strings support {variable} placeholders the launcher replaces at runtime:
| Variable | Example | Description |
|---|---|---|
{version} | 2026.27.7 | The version from the version() call |
{os} | darwin, linux | Operating-system kernel name |
{arch} | aarch64, x86_64 | CPU architecture (Bazel naming) |
{target} | aarch64-apple-darwin, x86_64-unknown-linux-musl | LLVM target triple |
version.axl is parsed as Starlark syntax but not evaluated — only string literals and function-call structure are extracted, so expressions, variables, and conditionals are not available.
Caching
Downloaded binaries are cached under the system cache directory:- macOS:
~/Library/Caches/aspect/launcher/ - Linux:
~/.cache/aspect/launcher/
ASPECT_CLI_DOWNLOADER_CACHE environment variable.
Set ASPECT_DEBUG=1 to log the download and cache resolution flow if you need to debug what the launcher is doing.
CI considerations
CI runners share the same launcher behavior as developer machines, so a committed.aspect/version.axl pins the CLI version everywhere at once.
- Aspect Workflows CI runners ship with the launcher pre-installed; pinning a version updates both developer machines and runners with a single PR.
- GitHub Actions / other CI — see How to install the Aspect CLI for installing the launcher in your CI image. Once installed, the launcher reads the same
.aspect/version.axlfrom the checkout.

