I finally moved our main service off dep and onto Go modules, and the only real regret is that I waited this long. Modules have been the default for years now, the wider ecosystem has long since stopped pretending dep is alive, and yet we had a Gopkg.toml and a vendor/ tree sitting there like a fossil. Inertia is a hell of a thing.
The actual conversion is almost anticlimactic. From the repo root:
go mod init github.com/ourorg/ourservice
go mod tidy
go mod init reads the existing Gopkg.lock if it's there and seeds the require block with your pinned versions, which is a genuinely nice touch. Then go mod tidy goes off, walks the import graph, adds anything you actually use, and removes anything you don't. The diff on go.mod was readable in one screen. That alone felt like a small victory after years of squinting at Gopkg.lock.
The bits that did need attention:
- A couple of dependencies had import paths that had moved.
dephad been quietly following redirects; modules want the canonical path. Two find-and-replaces sorted it. - One library we relied on had no proper semantic version tags, so modules pinned a pseudo-version (
v0.0.0-2023...-abc123). Ugly, but correct, and honestly more honest than pretending it was a release. - Our internal fork of a thing needed a
replacedirective pointing at the right module path. That's the one feature I'd reach for again immediately; it's far cleaner than the vendoring contortions we used before.
The thing I want to flag for anyone still on the fence: drop the vendor/ directory unless you have a hard reason to keep it. With modules and the proxy, a clean go build pulls and caches everything anyway, and the build is reproducible because go.sum records the hashes. We were carrying tens of thousands of vendored files in version control for no benefit. Deleting that directory was, frankly, the most satisfying part of the whole exercise.
Build times didn't change much, CI got a little simpler because we stopped reinstalling dep in the pipeline, and the mental overhead of "how do I add a dependency again" dropped to go get. No drama, no heroics. Just a tool we should have retired ages ago, finally retired.