You’re staring at a monorepo with Go, protobuf, and a handful of generated files. make is groaning. Your CI takes 40 minutes. Someone mentions Bazel, and you think: that’s the Google thing, right? Sounds like overkill.
It’s not. Or rather – it is, but that’s the point.
Bazel treats your build like a pure function. Same inputs, same outputs, every time. It caches aggressively, parallelizes ruthlessly, and forces you to declare your dependencies honestly. The learning curve is steep. The payoff is that builds stop being something you dread.
I’ve been going deep on the Bazel ecosystem – not just the core build system, but the tools orbiting it: Gazelle for automatic BUILD file generation, rules_go for Go projects, bzlmod for dependency management. Each one solves a real problem, and each one has its own set of sharp edges.
This series covers the territory I’ve explored so far:
| Topic | What’s in it |
|---|---|
| Caching | Skyframe, action cache, CAS, repository cache – how Bazel avoids redoing work |
| Dependency management | bzlmod and external dependencies |
| Skyframe | The evaluation framework underneath everything |
| Configuration | bazelrc, configs, bazelisk |
| Query | Interrogating your build graph |
| Telemetry | Profiling, Build Event Protocol |
| Remote execution | Distributing builds across machines |
| Gazelle | System design, extensions, how it resolves deps |
| rules_go | Building and testing Go with Bazel |
| IDL solutions | Protobuf, gRPC, and friends |
The list keeps growing. That’s how Bazel works – you pull one thread and three more appear.