bazoekt: easy code indexing and search for your Bazel projects

December 17, 2023

Update 2026-04-17: Bazoekt has been modernized and revived. Sourcegraph has taken over maintenance of zoekt, but what they actually did was disable the old repo and dismantle the zoekt infrastructure, so it couldn’t be compiled. I took over the old version of zoekt, spruced it up so that it builds again, and put it up at https://github.com/filmil/zoekt. Then revived bazoekt on top of that, see it at: https://github.com/filmil/bazoekt

Since I can’t remember anything these days, I often find myself sifting through my code looking for specific keywords. Sometimes grep isn’t quite enough, and something more is needed.

I am also a fan of Bazel, and have recently decided to try using it as much as possible as a way to automate away the building pains. Bazel is nice because it removes almost all the project setup efforts. The flip side is the complexity, which has been criticized before.

It occurred to me recently that we have the tools to add code indexing easily to any bazel project. H.-W. Nijenhuis (incidentally also one of the original authors of Bazel) has published a program by the tongue-in-cheek name “zoekt” (“you seek” in Dutch, but apparently there’s a back story to it) that does fast trigram-based indexing and search. The program has stopped being developed a long time ago, but still works, and does its job well. Which, frankly, these days is a rarity. Sourcegraph has taken over the development of “zoekt”, but last time I checked their repository was broken. The original repository however compiles and runs without a hitch.

One thing I appreciated about zoekt is how uncomplicated it is. Especially versus tools like kythe or sourcegraph, which are next to impossible to set up. And for sure not worth setting up on a local machine.

It occurred to me that I could automate indexing of bazel projects by adding a few well-chosen scripts to an existing a Bazel repo, and feeding the default settings to zoekt for further processing. You could then easily add the result to any Bazel project at a moment’s notice. Zoekt has other approaches and options, such as indexing git repositories, or pulling and indexing public git repos and such. But most of those are not required if the only thing you want is to index the code you are working on right now.

And after some 30 minutes of tinkering (and frankly, a few hours resolving bizarre bazel issues), “bazoekt” was born. Once you make it part of your Bazel project setup (e.g. in your WORKSPACE file), it will download and prepare itself the first time you run any of the commands below. Like magic.

The details are available at https://github.com/filmil/bazoekt. But in short:

Installation

First, configure your .bazelrc to pull modules from the custom registry. Add the following to your .bazelrc to get access to my bazel registry:

common --registry=https://raw.githubusercontent.com/filmil/bazel-registry/main
common --registry=https://bcr.bazel.build

Next, add the following into your MODULE.bazel file:

bazel_dep(name = "bazoekt", version = "0.0.8")

This should be enough to have bazoekt available to you.

Index

Update your index, by occasionally running the following:

bazel run @bazoekt//:index

Start the web server for the index:

bazel run @bazoekt//:serve

Visit http://localhost:6070 to search.

Epilogue

These allow you to change some of the trivial default settings to other trivial settings. Those are a tiny subset of the configuration options offered by “zoekt”, but I contend that changing them will rarely be needed.

While this is something I cobbled together for my own use, I would love to hear from anyone who may visit https://github.com/filmil/bazoekt and decide to give it a try.