Go 1.11 introduced modules, which sets the foundation for robust dependency management.
Pre-Go 1.11 dependency management
Prior to Go 1.11, packages were managed by configuring the GOPATH environment variable. Some projects set the GOPATH to somewhere in the project’s repository, whereas others rely on a system-wide GOPATH to be set. The first solution is more popular for developers that like to vendor their dependencies (in other words, keep a copy of all dependencies with the project), whereas others rely on tools to manage specific versions.
Several different types of tools exist for managing dependencies, and this wiki resource lists the more popular ones.
One of the more interesting ones was https://gopkg.in, which used urls such as:
I’ll explain in more detail how gopkg.in relates to vgo later.
The popularity of dependency management tools showed demand, but the lack of consensus limited the design space since no tool could make assumptions about how dependencies are managned.
To solve these problems, the Go team built dep,
which was the official experiment for dependency management. This tool went
with a fairly traditional package managament solution a la
with having each package provide metadata, such as version, branch, or revision.
Resolving dependencies follow semantic versioning guidelines,
which can result in multiple versions of the same dependency being compiled in by
During the experiment phase, the community and the Go team ran into a variety of problems with the fundamental design of dep, mostly revolving around it not fitting in nicely with the design of existing tools.
With vgo, the Go project returned to the simple tooling that the project started with, which roughly coincides to the implementation of gopkg.in.
One of the most significant changes is moving away from the GOPATH variable, which existing Go dependency managers had to work around.