0.1.1 Bazelisk & .bazelversion

When you open a Bazel repository, check .bazelversion to see which Bazel release the project expects. For a normal project pin, the file contains one exact version:

9.0.0

Teams commonly use Bazelisk as their bazel command. It reads the checked-in pin, downloads that Bazel release if necessary, and delegates the command to it1. When developers and CI use a launcher that honors the file, every clone starts from the same Bazel version instead of whichever binary happens to be installed on the machine.

The file instructs a compatible launcher. It does not enforce the selected version by itself. For advice on choosing a release and coordinating upgrades, see P.4.2 Release Cadence & LTS.

From The Project Pin To A Bazel Process

Bazelisk is typically installed on your PATH as bazel. When you type bazel, you're actually running Bazelisk, which:

  1. Looks for a .bazelversion file in the current directory or any parent directory.
  2. Downloads the specified Bazel version (if not already cached locally).
  3. Delegates the command to that version.

You use bazel build, bazel test, and other commands as if Bazel were installed directly.

Install Bazelisk Once

First check the repository's setup instructions: some projects provide their own bootstrap script or a checked-in launcher. If they do not, install Bazelisk with the normal tool for your platform2:

macOS:

brew install bazelisk

Windows:

winget install Bazel.Bazelisk

Chocolatey (choco install bazelisk) and Scoop (scoop install bazelisk) are also supported.

Linux: download the binary for your architecture from the Bazelisk releases page, name it bazel, make it executable, and place it on your PATH.

If Node.js is already part of your toolchain, NPM is another cross-platform option:

npm install -g @bazel/bazelisk

Then run this from the repository root:

bazel version

The first run may download the pinned Bazel binary. In the output, the Bazel Build label should match .bazelversion. Bazelisk also prints its own wrapper version.

.bazeliskrc

Some teams also check in .bazeliskrc. While .bazelversion answers "which Bazel version?", .bazeliskrc configures the launcher itself—for example, a fallback version or a custom Bazel distribution.3,2 It is not a BUILD file and it does not mark the repository root. If the repository also has a tools/bazel wrapper, 3.2.8 tools/bazel Wrapper explains how that extra layer works.

key takeaway

The reproducible setup has two parts: an exact .bazelversion pin committed to the repository and a launcher used consistently by developers and CI. Bazelisk honors that pin, fetches the requested release when needed, and delegates the command. bazel version verifies which Bazel process actually ran.

extra

How Bazelisk Resolves the Version

When Bazelisk starts, it walks a priority chain to decide which Bazel version to use2:

  1. The USE_BAZEL_VERSION environment variable — highest priority. Useful for one-off testing (USE_BAZEL_VERSION=8.1.0 bazel build //...) without modifying checked-in files.
  2. A USE_BAZEL_VERSION entry in .bazeliskrc at the repository root.
  3. A .bazelversion file in the current directory or any parent directory.
  4. The USE_BAZEL_FALLBACK_VERSION environment variable — a safety net with configurable behavior (error:, warn:, or silent: prefix).
  5. If nothing is set, Bazelisk falls back to the latest stable release. A checked-in exact version avoids that unpinned drift.

Beyond exact version numbers like 9.0.0, Bazelisk understands several other formats2:

  • 8.x — floating version, resolves to the latest release in the 8.x LTS series.
  • 8.1.0rc2 — release candidates for testing upcoming releases.
  • Git commit hashes — for testing specific Bazel commits.
  • last_green / last_rc — latest CI-passing commit or most recent release candidate, used by contributors working on Bazel itself.

For day-to-day work, prefer an exact pinned version. Floating versions are more useful for deliberate upgrade testing than for keeping developer and CI environments aligned.

Bazelisk also supports tools/bazel wrappers and custom Bazel forks. 3.2.8 tools/bazel Wrapper covers the wrapper pattern in detail.

Check your understanding · 2 questions

1.True or false: how Bazelisk manages the Bazel binary.

Choose True or False for each sentence

Bazelisk is installed once and uses .bazelversion to decide which Bazel binary to download and run.
If .bazelversion is absent, Bazelisk refuses to run any command.
Running bazel version with Bazelisk installed shows both the Bazelisk wrapper version and the underlying Bazel version.
Each developer should install the correct Bazel version manually to match the project's requirements.

2.Match each Bazelisk configuration mechanism to what it controls:

Drag each answer onto the matching prompt, or click an answer and then click a prompt

Answers
.bazelversion
USE_BAZEL_VERSION env var
.bazeliskrc
0 of 2 answered

Footnotes

  1. Bazel Training 101 (Part 5): Installing Bazel — Bazelisk as recommended installation method, .bazelversion behavior, available via Homebrew and NPM

  2. Bazelisk README — current platform installation methods, version resolution algorithm, version formats, and configuration reference 1 2 3 4

  3. Bazel 101 Training (Part 6): Create a repository — .bazelversion and .bazeliskrc as key repository files