tools/bazel shell wrapper in your workspace and Bazelisk runs it on every bazel invocation. The wrapper sends each command to the right tool: aspect for the verbs aspect wraps (build, test, lint, format, gazelle, buildifier, delivery, any custom .axl task), and 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 run. aspect then forwards each flag it doesn’t define to Bazel in the slot you typed it in: after the verb as a command option, before it as a startup option. A flag the task defines itself stays with the task. See flag passthrough.
Requires Bazelisk. The
tools/bazel hook is a Bazelisk feature; the real bazel binary doesn’t look for it. It works when the bazel on your team’s PATH is Bazelisk.bazel run stays on vanilla bazel by default: aspect run exists, but its semantics don’t match bazel run closely enough to replace 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 snippets for your shell’s rc file that toggle the escape hatches below. Re-running is idempotent: an up-to-date copy is left alone, and a newer release is offered as an upgrade.
Requires Aspect CLI v2026.39.10 or newer. 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. - 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.
