# Gazelle for Bazel BUILD File Generation

> bazel-contrib/bazel-gazelle generates and updates Bazel BUILD files from source trees and project conventions. It handles Go and protobuf natively, while other languages depend on extensions.

**bazel-contrib/bazel-gazelle** — Gazelle generates and updates Bazel BUILD files. It supports Go and protobuf natively and many more languages and rule sets through extensions.

- Repository: https://github.com/bazel-contrib/bazel-gazelle
- Stars: 1,427 · Forks: 453
- Language: Go
- License: Apache-2.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/bazel-contrib-bazel-gazelle

## Gazelle and BUILD File Drift

Gazelle addresses a concrete Bazel maintenance problem. BUILD files describe source files, dependencies, targets, and build options, but hand-editing them becomes repetitive as a repository changes. The README says Gazelle can create BUILD files for projects that follow language conventions. It can also update existing files when sources, dependencies, or options change.

This makes Gazelle relevant to maintainers who want generated metadata to remain aligned with a source tree. It is intended for Bazel users working primarily with Go and protobuf. Teams working with other languages can use extensions, although those extensions have separate repositories and may have different feature sets.

Gazelle is not the build executor itself. Bazel continues to build and execute targets. Gazelle generates or updates the BUILD metadata that describes those targets. This boundary matters when evaluating whether a repository needs automated BUILD generation or a different Bazel management approach.

The practical value is consistency. A generator can apply repeatable rules across many directories instead of asking maintainers to make the same structural changes repeatedly. That benefit disappears when project conventions are unusual, handwritten targets dominate the directory, or generated rules do not match the language extensions in use.

## Go Modules and Protobuf Rules

Go and protobuf are the two language areas included directly in `bazel-gazelle`. For Go, the quick start uses Bzlmod extensions from `rules_go` and `gazelle`. The `go_sdk` extension downloads a selected Go SDK, while `go_deps` reads `go.mod` and exposes repositories that can be registered with `use_repo`.

A minimal Bzlmod configuration follows this form in the README. The listed versions are examples that the README says to replace with current versions available in the Bazel Central Registry.

```bzl
bazel_dep(name = "rules_go", version = "0.64.2")
bazel_dep(name = "gazelle", version = "0.54.0")

go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
go_sdk.download(version = "1.27.2")

go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//:go.mod")

use_repo(
    go_deps,
    "org_golang_x_net",
    "org_golang_x_tools",
)
```

For protobuf, Gazelle supports `proto_library`. Language-specific rules such as `go_proto_library` come from other extensions. This prevents users from assuming that native protobuf generation automatically creates every protobuf target required by another rule set.

The root BUILD file can define the default integration without a custom `gazelle_binary`:

```bzl
load("@gazelle//:def.bzl", "gazelle")

gazelle(name = "gazelle")
```

Configuration can be supplied through a directive comment. The README example uses:

```bzl
# gazelle:prefix example.com/my/module/path
```

That prefix affects how generated Go labels are formed. It is an explicit configuration choice, not a value Gazelle can infer for every repository.

## Installing Gazelle and Running It

The README provides a Bzlmod setup. For a Gazelle-only installation, add the Gazelle module dependency to `MODULE.bazel`:

```bzl
bazel_dep(name = "gazelle", version = "0.54.0")
```

The version is copied from the README example, whose comment instructs users to replace it with the latest version available from the BCR. The root BUILD file then loads the `gazelle` and `gazelle_binary` rules. The example also shows two extension locations, although the first path depends on repository setup that the README does not fully define.

After defining the rules, invoke the repository's Gazelle target through Bazel:

```bash
bazel run //:gazelle
```

This is the first useful operation for an existing Go repository. Gazelle should create or update BUILD files according to the configured Go and protobuf extensions. Review the resulting files before committing them, especially if the repository contains handwritten rules.

Gazelle can also be built and installed as a command line tool. The documented direct form is:

```bash
gazelle [fix|update] [flags...] [directories...]
```

The bracket notation describes the command grammar rather than literal characters to paste. The Bazel invocation is normally the clearer first use because it uses the declared binary and extension set.

For Go projects using Bzlmod, the README points to the Go Bzlmod documentation. It also documents a `WORKSPACE` setup in `workspace.md`, so teams using that dependency model should follow that file rather than copying the Bzlmod configuration unchanged.

## Directory Scans, Updates, and Diff Checks

Gazelle can scan selected directories and accept additional flags through Bazel:

```bash
bazel run //:gazelle -- [flags...] [directories...]
```

The README documents `-mode=diff` as a way to print proposed changes and return a non-zero status when changes are required:

```bash
bazel run //:gazelle -- -mode=diff
```

This mode is useful as a repository check because it exposes generator output without applying it. It can help reviewers see whether new Go files, dependencies, or protobuf sources are missing from BUILD files. It does not, by itself, establish that every resulting Bazel target builds successfully. The README describes generation checks rather than a complete build verification workflow.

The normal run updates files in the selected repository areas. The direct binary accepts `fix` or `update` before flags and directories. The README does not detail every difference between those modes, so users who need precise semantics should consult `gazelle-reference.md`.

Gazelle also has a `gazelle_test` rule for execution through `bazel test`. The README says that this rule runs locally and cannot be cached. Teams should not describe it as a remote cached verification target. Its role is to check generated BUILD state under the configured Gazelle setup.

## Extensions Beyond Go and Protobuf

Gazelle uses extensions for languages beyond its native Go and protobuf support. The README lists extensions for Haskell, Java, JavaScript and TypeScript, Kotlin, Python, R, Rust, Starlark, Swift, and C/C++. These are not all maintained inside `bazel-gazelle`.

The language-specific approach creates clear ownership boundaries. The `rules_jvm` extension generates Java targets such as `java_library`, `java_binary`, `java_test`, and `java_test_suite`. The `rules_python` extension generates `py_library`, `py_binary`, and `py_test`. The `gazelle_rust` extension generates `rules_rust` targets. Other listed extensions target different language rule sets.

A `gazelle_binary` selects which extensions participate in generation. The README's Gazelle-only example includes extension locations for Starlark and C/C++, while the Go example says that the default binary uses the proto and Go extensions. This means that support for a language is not equivalent to installing Gazelle alone.

The README marks Kotlin support as still under development and tells users to check that extension's README for current features. Extensions may also lag the current core release, have separate release schedules, or support only part of a language's Bazel rule set. Adoption decisions should include the extension repository and its supported targets, not just the Gazelle version.

The core repository contains `extend.md`, `def.bzl`, `extensions.bzl`, `language`, and `repo`. Based on this layout, extension interfaces and language implementations are distinct from the command line entry point. The README also advises that language-specific extensions should generally live in their language-specific repository rather than in `bazel-gazelle`.

## Existing BUILD Files and Merge Risk

Updating existing BUILD files is more difficult than generating empty ones. A repository may contain handwritten targets, macros, visibility settings, tags, test metadata, or rules that Gazelle does not recognize. The README says Gazelle can update existing BUILD files, but it does not enumerate the merge behavior for every custom attribute or rule.

The repository includes directories named `merger` and `config`, indicating that merge and configuration are separate implementation areas. That structure does not, by itself, guarantee that all manual content will remain untouched. The documented `-mode=diff` command is the clearest first check for this boundary.

A practical adoption sequence is to run diff mode in a clean working tree, inspect changed files, and then update only the directories covered by the project's intended Gazelle scope. This is a concrete use of the documented command, not a claim about behavior that the README does not specify. If a large amount of manual metadata changes, the extension or configuration is probably not aligned with the repository's conventions.

Gazelle is a poor fit for projects that want completely handwritten BUILD files but happen to install Gazelle for no reason. It is also a poor fit when custom build semantics cannot be expressed through the selected rule sets. In those cases, maintaining the files directly may be clearer than introducing a generator that repeatedly proposes changes.

## Release Lines, Licensing, and Upgrade Cost

The repository uses the `Apache-2.0` license and includes a `LICENSE` file. This identifies the stated license, but it does not replace an organization's review of license obligations. Users should not infer additional compatibility or distribution permissions beyond the license text.

The repository is not archived, and its last push was on 2026-10-15. The recent release list includes `v2.0.0-beta.2` on 2026-10-08, `v1.0.0-beta.1` on 2026-10-02, and `v2.0.0-beta.1` on 2026-10-02. These are beta releases. A project should decide which release line it intends to follow and read the corresponding documentation before changing an established integration.

The README quick start still shows `0.54.0` for the `gazelle` BCR dependency, while the recent release list contains newer beta versions. Its comment tells readers to replace versions with the latest versions available on the BCR. That instruction should be followed rather than copying a release tag from repository history into a module dependency without checking Bzlmod compatibility.

Upgrade work can include `MODULE.bazel`, `rules_go`, the Go SDK, `go_deps`, language extensions, directives, and generated BUILD files. The repository's `go.mod` declares `go 1.24.12` and pins several Go, Bazel, and protobuf-related module dependencies. The README does not provide a complete upgrade procedure or compatibility matrix. Projects should treat a version upgrade as a configuration and generated-output change, not as a blind version-number replacement.

## Conclusion

Adopt Gazelle when the repository follows source conventions and needs repeatable BUILD file generation, especially for Go or protobuf. Do not assume that extensions cover custom rules without checking their documentation. Verify module versions, selected extensions, merge behavior, and the generated diff before committing changes. The repository is not archived, and its last push was on 2026-10-15.

## FAQ

### How do I install and run Gazelle for a Bazel repository?

The README documents a Bzlmod setup that adds `gazelle` to `MODULE.bazel`, defines Gazelle rules in the root BUILD file, and runs `bazel run //:gazelle`. It also supports direct invocation when a Gazelle binary has been built and installed.

### Does Gazelle support languages other than Go and protobuf?

Yes, through extensions. The README lists extensions for Haskell, Java, JavaScript and TypeScript, Kotlin, Python, R, Rust, Starlark, Swift, and C/C++, but these extensions live in separate language-specific repositories.

### How can I inspect Gazelle changes before updating BUILD files?

Run `bazel run //:gazelle -- -mode=diff`. The README says this mode prints the changes Gazelle would make and exits non-zero if changes are needed.

### Can Gazelle generate Go dependency repositories from go.mod?

The Go Bzlmod example uses `go_deps.from_file(go_mod = "//:go.mod")` to read `go.mod`, then registers generated repositories with `use_repo`. The README also describes `go_repository` support for generating BUILD files for external repositories.

## Sources

- [bazel-contrib/bazel-gazelle on GitHub](https://github.com/bazel-contrib/bazel-gazelle)
- [Issues](https://github.com/bazel-contrib/bazel-gazelle/issues)
- [License: Apache-2.0](https://github.com/bazel-contrib/bazel-gazelle/blob/master/LICENSE)
- [README](https://github.com/bazel-contrib/bazel-gazelle/blob/master/README.md)
- [Releases](https://github.com/bazel-contrib/bazel-gazelle/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/bazel-contrib-bazel-gazelle
