Preferences

I like that Go decided to natively support this. But since it’s keeping the dev dependencies in the same go.mod, won’t it make the binary larger?

In Python’s uv, the pyproject.toml has separate sections for dev and prod dependencies. Then uv generates a single lock file where you can specify whether to install dev or prod deps.

But what happens if I run ‘go run’ or ‘go build’? Will the tools get into the final artifact?

I know Python still doesn’t solve the issue where a tool can depend on a different version of a library than the main project. But this approach in Go doesn’t seem to fix it either. If your tool needs an older version of a library, the single go.mod file forces the entire project to use the older version, even if the project needs—or can only support—a newer version of the dependency.


> won’t it make the binary larger?

No. The binary size is related to the number of dependencies you use in each main package (and the dependencies they use, etc). It does not matter how many dependencies you have in your go.mod.

Ah, thanks. This isn't much of an upgrade from the `tools.go` convention, where the tools are underscore-imported. All it does is provide an indication in the `go.mod` file that some dependencies come from tools.

Plus, `go tool <tool-name>` is slower than `./bin/<tool-name>`. Not to mention, it doesn’t resolve the issue where tools might use a different version of a dependency than the app.

Exactly. You lose build isolation for those tools, but you have the convenience of shipping something tested and proven (ideally) alongside the project they support. At the same time, this mess all stays isolated from the parent environment which may be the bigger fight that devs have on their hands - not everyone is using Nix or container isolation of some sort.

I also see this as sugar for `go build` or even `go run`. Or as something way easier than the `go generate` + `//go:generate go run` hack. So we can look at this as a simple refinement for existing practices.

go tool is only slower when (re-)compilation is needed, which is not often. You'd have to pay the same price anyway at some point to build the binary placed in ./bin.
I'm actually not 100% on this; there is a cache, and it should speed things up on subsequent runs, but maybe not as much as one might think: https://www.hackerneue.com/item?id=42864971
> In Python’s uv, the pyproject.toml has separate sections for dev and prod dependencies.

If you want, you can have multiple ".mod" files and set "-modifle=dev-env.mod" every time you run "go" binary with "run" or "build" command. For example, you can take what @mseepgood mentioned:

> go tool -modfile=tools.mod mytool

Plus, in last versions of the Go we have workspaces [0][1]. It is yet another way to easily switch between various environments or having isolated modules in the monorepo.

[0]: https://go.dev/blog/get-familiar-with-workspaces

[1]: https://go.dev/doc/tutorial/workspaces

This item has no comments currently.