Go 1.24's go tool is one of the best additions to the ecosystem in years

Go 1.24’s new `go tool` command, which lets projects declare and run Go-based developer tools via `go.mod`, is being welcomed as a quality-of-life improvement for reproducible tooling, especially in teams without heavy-duty build systems like Bazel. Critics, however, argue that mixing tool dependencies into the main module graph risks version conflicts, go.mod “pollution,” and weaker isolation compared to approaches using separate mod files, Nix-style environments, or Docker. The debate highlights broader frustrations and trade‑offs around Go’s dependency management philosophy, performance priorities, and how tightly build tools should be coupled to application code.

Perceived Benefits of go tool

  • Many see first-class support for per-project tools as closing a long-standing gap around “metaprogramming” and codegen that had been handled ad‑hoc with go generate, Makefiles, or tools.go.
  • Advocates say it:
    • Ensures consistent tool versions across developers and CI.
    • Integrates with Go’s reproducible builds and security scanning.
    • Is simpler and more “Go-native” than Bazel/Buck for pure-Go shops.
  • Some teams at large companies report that something like go tool is “sorely needed” even with sophisticated internal tooling.

Concerns About go.mod Pollution and Dependency Isolation

  • A major complaint: tool dependencies are added as regular indirect deps in go.mod, with no clear annotation or separation from runtime deps.
  • This:
    • Bloats go.mod (one example: 93 → 247 lines), making manual review difficult.
    • Merges tool and app dependency graphs, so version conflicts and vulnerability noise become more likely.
  • Go team rationale: keeping a single dependency graph simplifies security scanners and tooling; module graph pruning prevents most tool deps from propagating downstream.
  • Workarounds and alternatives:
    • Use comments (desired but not yet implemented) or a separate tools.mod with -modfile.
    • Continue using go install, Makefiles, local bin/, or env tools (Nix, flox, devenv, mise).

Build Performance and Caching Behavior

  • Some worry that rebuilding on every go tool call is too slow, especially on CI.
  • Clarifications:
    • Tools aren’t fully rebuilt each time; Go checks they’re up to date and uses caching (extended in 1.24 to cache final executables for both go run and go tool).
    • Benchmarks show large speedups from caching, but there is still noticeable overhead for large packages and version resolution.

“Dev Dependencies” and Version Management Model

  • go tool is essentially Go’s take on dev-dependencies, but:
    • There are no version ranges; Go uses Minimum Version Selection with semver-major split into distinct modules.
    • Some argue this is elegant and deterministic; others think relying on “newer is always compatible” is unrealistic and risky.
  • Critics argue tools should keep their own isolated dependency graphs (like go install module@version or a Nix shell) so that:
    • Tools aren’t run against untested dependency versions.
    • Application upgrades aren’t blocked by tool constraints (and vice versa).

Language-Specific vs General Build/Tooling Systems

  • Several compare go tool with:
    • Bazel/Buck/Pants (powerful, cross-language, but complex and heavy).
    • Nix, conda, flake-based or containerized dev environments (more generic & tool-agnostic).
  • One camp argues language-specific tooling gives a better UX, stronger conventions, and less configuration.
  • Another favors language-agnostic environments where all tools (Go and non-Go like protoc) are declared and versioned together, seeing go tool as partial and Go-centric.

Broader Sentiment About Go Tooling and Process

  • Some praise Go modules and MVS as best-in-class vs Java/Python/JS ecosystems; others describe Go’s module tooling as confusing, “non-deterministic,” or historically late and opinionated.
  • A subset sees go tool as a modest quality-of-life improvement, not a game-changer, and worry it nudges the community into a problematic pattern of mixing tool and app deps.
  • Others are unconcerned because the feature is optional and compatible with existing approaches like tools.go, Makefiles, or external env managers.