Introduction
Bazel is an open-source build and test tool originally developed at Google to handle their massive monorepo. It provides fast, reproducible builds across languages like Java, C++, Go, Python, and TypeScript by leveraging aggressive caching and parallel execution. If your project spans multiple languages or targets multiple platforms, Bazel eliminates the patchwork of build scripts.
What Bazel Does
- Builds and tests code across 20+ languages using a unified dependency graph
- Provides hermetic builds that produce identical outputs regardless of host environment
- Caches build artifacts locally and remotely so unchanged modules are never rebuilt
- Executes build actions in parallel across all available CPU cores
- Supports remote execution to distribute builds across a cluster of workers
Architecture Overview
Bazel reads BUILD files that declare targets and their dependencies, constructing a directed acyclic graph of the entire project. It hashes every input (source files, toolchains, flags) to create a content-addressable cache. When you run a build, Bazel compares hashes against its action cache and only re-executes actions whose inputs changed. The Starlark configuration language (a Python dialect) lets you write custom rules, macros, and aspects to extend Bazel for any toolchain.
Self-Hosting & Configuration
- Install Bazelisk as a version manager that auto-downloads the right Bazel version per project
- Define a WORKSPACE or MODULE.bazel file at the repo root to declare external dependencies
- Write BUILD files in each package directory listing targets, sources, and deps
- Configure .bazelrc for shared build flags like --remote_cache for team-wide caching
- Use rules_docker, rules_go, rules_python etc. from the Bazel Central Registry for language support
Key Features
- Incremental builds that only recompile what changed, cutting CI times by 10x on large repos
- Remote caching and remote execution support for distributed build farms
- Sandboxed actions ensure builds cannot leak host state or produce non-reproducible artifacts
- First-class support for cross-compilation and multi-platform targeting (Linux, macOS, Windows, mobile)
- Extensible rule system via Starlark allowing custom build logic for any toolchain
Comparison with Similar Tools
- Make — simple and ubiquitous but lacks dependency graph intelligence and reproducibility guarantees
- Gradle — great for JVM projects but slower on large monorepos and less hermetic by default
- Buck2 (Meta) — similar philosophy to Bazel with Starlark rules but smaller ecosystem and community
- Pants — Python-focused monorepo build system, simpler setup but narrower language coverage
- Turborepo — optimized for JS/TS monorepos only, not designed for multi-language builds
FAQ
Q: Is Bazel only for Google-scale projects? A: No. Bazel benefits any project with multiple languages, shared libraries, or slow builds. Even mid-size teams see 5-10x CI speedups from caching.
Q: How steep is the learning curve? A: The initial setup (WORKSPACE, BUILD files, toolchain rules) takes effort. Once configured, daily usage is straightforward with commands like bazel build and bazel test.
Q: Can Bazel build Docker images? A: Yes. The rules_oci and rules_docker rulesets let you build container images directly from BUILD targets without a Docker daemon.
Q: Does Bazel work with existing Maven or npm projects? A: Yes. Tools like rules_jvm_external pull Maven deps, and rules_js handles npm packages, letting you migrate incrementally.