aspect-launcher, a small binary added to your PATH as aspect. This launcher downloads and runs the version of the Aspect CLI binary configured in your repository. It operates similarly to how bazelisk fetches the configured version of Bazel, or how nvm or n- manages Node.js versions.
Find the latest releases at https://github.com/aspect-build/aspect-cli/releases.
Install with curl
The curl script works on macOS and Linux without any prerequisite package manager. Run:aspect-launcher binary as aspect on your PATH.
Updating with curl
To update theaspect-launcher with curl, re-run the installation script:
Install with Homebrew (macOS)
To install via Homebrew, run the following command:aspect-launcher binary as aspect on your PATH.
Updating with Homebrew (macOS)
To update theaspect-launcher with Homebrew, run the following commands:
Install the Aspect CLI with direnv and multitool
This method assumes your development environment uses bazel_env.bzl. For examples, refer to the aspect-starters repositories on GitHub.
- Add
aspectto the multitool lockfile, as shown in this example. - Build and run your
bazel_envtarget. Bazel will handle the installation ofaspect, making it available on your PATH.
bazel_env”:
Install with GitHub Actions
Use theaspect-build/setup-aspect action. It installs the launcher, installs Bazelisk (unless bazel is already on PATH), wires --disk_cache / --repository_cache to the GHA cache, and exchanges your ASPECT_API_TOKEN for a short-lived JWT, all in one step. The same one-liner works on provider-hosted runners (ubuntu-latest, macos-latest) and on Aspect Workflows CI runners.
.aspect/version.axl (see version pinning), the launcher reads that file and downloads the matching CLI on first aspect invocation, so local and CI stay in sync without bumping a launcher version in your workflow YAML.
Without setup-aspect
If for some reason you’d rather install the launcher inline (or you’re on a CI provider without an equivalent action, Buildkite, GitLab, CircleCI), the curl one-liner works:
setup-aspect does for you.
Install the Aspect CLI manually from GitHub
Visit the Aspect CLI Releases page on GitHub to download the appropriate binary for your platform, such asaspect-launcher-aarch64-apple-darwin for macOS arm64, or equivalents for other architectures and operating systems.
macOS example
-
Download the
aspect-launcher-aarch64-apple-darwinbinary from the Aspect CLI Releases page. -
In your terminal, run these commands to clear the untrusted developer attribute, make the binary executable, and move it to your PATH:
Keep your team typing bazel with the tools/bazel wrapper
A common objection when adopting the Aspect CLI is “we don’t want to teach our developers a new command name.” You don’t have to. Drop a tools/bazel shell wrapper into your workspace and Bazelisk will exec it on every bazel invocation, routing each command to the right tool: aspect for the verbs aspect wraps (build, test, lint, format, gazelle, buildifier, delivery, any custom .axl task), vanilla bazel for everything else (query, info, clean, …).
Your arguments are forwarded verbatim. The wrapper never inspects or rewrites a flag, it only picks which binary to exec, and aspect passes the flags it doesn’t recognize through to Bazel in the slot you typed them in.
Requires Bazelisk. The
tools/bazel hook is a Bazelisk feature, the real bazel binary does not look for it. This works if the bazel on your team’s PATH is Bazelisk, which is the most common setup (every Bazelisk release since 2019 honors the hook).bazel run is deliberately left on vanilla bazel: aspect run exists, but its semantics don’t line up closely enough with bazel run to shadow it transparently yet. Reach for aspect run directly when you want it, or add run to the verb list below once you’ve validated it for your workflows.
The Aspect CLI can drop the wrapper in for you. From anywhere in your workspace:
main), writes tools/bazel (executable) and tools/bazel.md, and prints optional rc snippets for your shell that turn the escape hatches below on and off. Pin a specific version with --version=<tag>. Re-running is idempotent: an up-to-date copy is left untouched, a newer release is offered as an upgrade. In CI, aspect setup tools-bazel-wrapper --check exits non-zero when tools/bazel is missing or stale so you can gate on it. aspect setup tools-bazel-wrapper --uninstall removes the files again.
Requires Aspect CLI v2026.38.14 or newer, which is where this command landed. On an older release, install the wrapper by hand instead, as shown next.
bazel for a shell session can set ASPECT_WRAPPER_SKIP=1 to bypass routing entirely.
Customize the verb routing
Two lists at the top oftools/bazel drive every routing decision. Edit them in your repo’s copy:
ASPECT_VERBS— the verbs routed toaspect. A verb in neither list is treated as a custom.axltask and also routes toaspect, so what listing one really buys is the fallback to vanillabazelwhenaspectisn’t installed. That only makes sense for verbs Bazel also has.BAZEL_VERBS— the closed set of Bazel commands. A verb here that is not inASPECT_VERBSgoes to vanillabazeluntouched (query,info,clean,mod,coverage, …). Update it only when Bazel adds a command.
- Send
build/testto vanillabazelinstead. Remove them fromASPECT_VERBSand they fall through to the realbazeluntouched. Keep the aspect-only verbs (lint,format,delivery,gazelle) listed sobazel lintand friends still reachaspect. Useful when your team wantsbazel buildto stay pure-Bazel but still pick upaspectfor the verbs Bazel doesn’t have. - Add
run, or your own aspect commands. Onceaspect runsuits your workflows, addruntoASPECT_VERBSsobazel runroutes through it.
aspect) lives next to the script: tools/bazel.md.
