Go Minimal Version Selection
Your go.mod asks for one version and you build against another. Paste a `go mod graph` and see the selection worked out: every version required, which module asked for it, and the shortest path from your main module to the requirement that won.
Nothing you paste is transmitted. There is no endpoint behind this page: the Go that resolves the graph is compiled to WebAssembly and runs in this tab, so your dependency graph never leaves the browser.
Start from one of these
The algorithm, in one sentence
The selected version of a module is the highest version required by anything in the build list. Not the newest that exists on the proxy — the newest that something actually asked for. That is the whole of minimal version selection, and it is why a Go build is reproducible without a lock file: adding a dependency can raise a version, and nothing else can.
The consequence people find surprising is the one this page is built to show: your own go.mod asking for v0.3.2 does not mean you get v0.3.2. If anything anywhere in your dependency graph asks for v0.3.7, that is what you build against — and the thing that asked may be three hops away and invisible in your go.mod.
Why the answer is a derivation
“golang.org/x/text is at v0.3.7” is a fact you can already read out of your go.mod. What you cannot read out of it is who asked for that. So every module here shows every version that was required, which module required each one, and the shortest requirement path from your main module to the requirement that won. Contested modules are listed first, because those are the rows anyone opens this page for.
Why it takes a graph and not a go.mod
A go.mod names your direct requirements. Resolving it would mean fetching each of them to read their requirements, and that needs a module proxy, a network and a cache — none of which exists on a page that runs entirely in your browser.
go mod graph is the requirement graph already expanded, so this is pure computation with nothing to fetch. That is also the honest boundary: a tool that claimed to resolve a go.mod without the network would be resolving something else and not telling you.
Version ordering, and the rule that catches people
Versions compare by semantic-version precedence. Major, minor and patch numerically; then a pre-release ranks below the release it precedes, so v1.0.0-rc1 loses to v1.0.0. That clause is the one most often implemented backwards, and backwards means selecting a release candidate over a release.
Two Go-specific consequences follow from the same rules. A pseudo-version like v0.0.0-20191109021931-daa7c04131f5 is a pre-release, so it sorts below any tagged release of the same version — which is exactly what you want when a module finally gets a tag. And +incompatible is build metadata, which semver ignores entirely: v2.0.0+incompatible and v2.0.0 compare equal.
One thing that is easy to get wrong
Selection follows requirements from every version reachable in the graph, not only the versions that end up selected. A module version that loses can still bring a dependency into your build, and an implementation that expanded only the winners would produce a build list the go command disagrees with.
The other tools
- Go Time Layout Converter — strftime to Go, and back — Convert a C strftime format string to a Go reference layout and back, directive by directive, with every unmappable directive named rather than guessed.
- Go Method Sets — why *T implements the interface and T does not — Paste a type and an interface and get both method sets computed by go/types, with the compiler's own error and the rule it follows from.
- Go Struct Field Alignment — offsets, padding, and what reordering saves — Paste a struct and get every field's offset, the padding between them, the total size, and a reordered version with the saving — for the architecture you choose.
- Go Slice Growth — what append actually does to the capacity — Watch a slice's capacity grow append by append: the formula's answer, the allocator's rounding, the size class it lands in, and the bytes left behind.
- Go Goroutine Dump Analyzer — read a SIGQUIT or panic stack dump — Paste a goroutine dump and get it grouped by state and by stack, with wait durations and the stacks held by far more goroutines than they should be.
- GOGC and GOMEMLIMIT Calculator — which one is actually deciding your heap — Compute both documented target-heap rules, see which one binds, and find out when GOGC has stopped having any effect at all.
- Go Benchmark Comparison — is that 4% real? — Paste two go test -bench outputs and get the Mann-Whitney U comparison: median change, p-value, and an honest answer when there is not enough data to tell.