Go 1.24's go tool is one of the best additions to the ecosystem in years
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, ortools.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 toolis “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.
- Bloats
- 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.modwith-modfile. - Continue using
go install, Makefiles, localbin/, or env tools (Nix, flox, devenv, mise).
- Use comments (desired but not yet implemented) or a separate
Build Performance and Caching Behavior
- Some worry that rebuilding on every
go toolcall 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 runandgo tool). - Benchmarks show large speedups from caching, but there is still noticeable overhead for large packages and version resolution.
- 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
“Dev Dependencies” and Version Management Model
go toolis 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@versionor 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 toolwith:- 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, seeinggo toolas 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 toolas 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.