> ## Documentation Index
> Fetch the complete documentation index at: https://site.aspect.build/llms.txt
> Use this file to discover all available pages before exploring further.

# aspect setup tools-bazel-wrapper

> Drop a tools/bazel wrapper into your workspace so bazel routes through the Aspect CLI for the verbs it wraps, and to vanilla Bazel for everything else.

Put a `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](/docs/cli/tasks/run#flag-passthrough).

| You type                                 | What runs                                 |
| ---------------------------------------- | ----------------------------------------- |
| `bazel build //... --keep_going`         | `aspect build //... --keep_going`         |
| `bazel test //... --test_output errors`  | `aspect test //... --test_output errors`  |
| `bazel --output_base /tmp/o build //...` | `aspect --output_base /tmp/o build //...` |
| `bazel lint --config=ci //src/...`       | `aspect lint --config=ci //src/...`       |
| `bazel query 'deps(//foo)'`              | vanilla `bazel`, unchanged                |
| `bazel my-custom-task //...`             | `aspect my-custom-task //...`             |

<Note>
  **Requires Bazelisk.** The <code>tools/bazel</code> hook is a [Bazelisk](https://github.com/bazelbuild/bazelisk) feature; the real <code>bazel</code> binary doesn't look for it. It works when the <code>bazel</code> on your team's <code>PATH</code> is Bazelisk.
</Note>

`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:

```sh theme={null}
aspect setup tools-bazel-wrapper
```

This downloads the wrapper and its reference doc from the latest release tag (never `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.

| Flag              | Default  | What it does                                                                                                                       |
| ----------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `--version <ref>` | `latest` | The aspect-cli release tag or commit SHA to take the wrapper from. `latest` resolves the newest release tag                        |
| `--check`         | off      | Exit non-zero when `tools/bazel` is missing or differs from `--version`, writing nothing. Use it as a CI gate                      |
| `--dry-run`       | off      | Print what would change without writing or deleting anything                                                                       |
| `--uninstall`     | off      | Remove `tools/bazel` and `tools/bazel.md`. Refuses a `tools/bazel` that isn't the Aspect wrapper. Can't be combined with `--check` |
| `--yes`           | off      | Skip the confirmation prompt when upgrading or uninstalling, and replace a `tools/bazel` that isn't the Aspect wrapper             |
| `--all-shells`    | off      | Print the rc snippets for bash, zsh and fish instead of only the shell in `$SHELL`                                                 |

<Note>
  **Requires Aspect CLI [v2026.39.10](https://github.com/aspect-build/aspect-cli/releases/tag/v2026.39.10) or newer.** On an older release, install the wrapper by hand instead, as shown next.
</Note>

Or drop it in by hand:

```sh theme={null}
mkdir -p tools
base=https://raw.githubusercontent.com/aspect-build/aspect-cli/v2026.39.10/tools
curl -fsSL "$base/bazel" -o tools/bazel
curl -fsSL "$base/bazel.md" -o tools/bazel.md
chmod +x tools/bazel
git add tools/bazel tools/bazel.md
```

Developers who prefer raw `bazel` for a shell session can set `ASPECT_WRAPPER_SKIP=1` to bypass routing entirely.

### Customize the verb routing

Two lists at the top of `tools/bazel` drive every routing decision. Edit them in your repo's copy:

```sh theme={null}
ASPECT_VERBS=(build buildifier delivery format gazelle lint test)
```

* **`ASPECT_VERBS`**: the verbs routed to `aspect`. A verb in *neither* list is treated as a custom `.axl` task and also routes to `aspect`, so what listing one really buys is the fallback to vanilla `bazel` when `aspect` isn'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* in `ASPECT_VERBS` goes to vanilla `bazel` untouched (`query`, `info`, `clean`, `mod`, `coverage`, …). Update it only when Bazel adds a command.

Two common edits:

* **Send `build` / `test` to vanilla `bazel` instead.** Remove them from `ASPECT_VERBS` and they fall through to the real `bazel` untouched. Keep the aspect-only verbs (`lint`, `format`, `delivery`, `gazelle`) listed so `bazel lint` and friends still reach `aspect`.
* **Add `run`, or your own aspect commands.** Once `aspect run` suits your workflows, add `run` to `ASPECT_VERBS` so `bazel run` routes through it.

```sh theme={null}
# Example: route bazel build/test to vanilla bazel, and wrap a custom "release" task
ASPECT_VERBS=(buildifier delivery format gazelle lint release)
```

The full reference (routing rules, every escape hatch, the trace output, and how the wrapper avoids recursing back into `aspect`) lives next to the script: [`tools/bazel.md`](https://github.com/aspect-build/aspect-cli/blob/v2026.39.10/tools/bazel.md).
