Gomod and go-libp2p

Let’s talk about go-libp2p’s recent adoption of gomod!

For context, go modules (gomod) are a dependency management solution provided in Go 1.11 and later that solves many of the problems with Go’s status quo.

Without modules, go will fetch remote dependencies from a git repo, for example from github, but it will always check out the master branch. If you have extremely good API versioning hygene and never make backwards incompatible changes, you might end up with a happy ecosystem of dependencies that never break their master branch. However, you’ll still be in an untenable situation, because the master branches of your dependencies are mutable references that may change tomorrow. There’s no way to guarantee that you can build your project on Monday, not touch it at all, and get the same result when you build it again on Tuesday.

Before gomod, IPFS and libp2p used a thing called gx that gives you a way to lock down your dependencies to an immutable reference - their IPFS hash. It’s really cool and was a great way to dogfood IPFS and realize tangible benefits of immutable data references. However, managing a complex web of dependencies using gx can be difficult, as changes need to bubble up through every affected dependent module. It also imposes some friction on people new to the project, who have to learn a new workflow to develop locally or contribute.

Cut to the present day, and gomod is well integrated into the core go toolchain. It gives us the deterministic builds we need, as well as a more sophisticated versioning system than “whatever’s on the master branch at the moment”. We dig it, and we made the switch in early 2019.

Since it’s still early days for gomod and libp2p, it would be great if people could comment with their experience using gomod in their dev workflows. Especially if there are things that worked better before the switch, lets figure that out and fix it.