Go namespaces code by where you fetch it from: import "github.com/thetrueares/boneclone", resolved over git. That’s a genuinely good property — no central registry, and you always know where to file a bug. But it also means the import path is the hosting provider, so your code is coupled to GitHub, GitLab, or wherever the repo happens to live today.
Iain Cambridge argues that coupling is expensive and cheap to avoid:
- Switching git hosts means changing import paths in your code and in every consumer’s code — otherwise they keep fetching the old copy.
- The cost is high enough that teams stop switching. He describes a company running GitLab, GitHub and Azure DevOps simultaneously because relocating repositories was “too big to get to” — so they just paid for three hosting services every month.
- This was part of why he built Boneclone, a tool for replicating skeleton code across multiple git hosts at once.
- The fix is vanishingly small: namespace under a domain you control.
go.iain.rocks/bonecloneinstead ofgithub.com/that-guy-iain/boneclone. The wider ecosystem already does this —go.uber.org,go.mongodb.org. - You serve one HTML page carrying
<meta name="go-import" content="go.iain.rocks/boneclone git https://github.com/that-guy-iain/boneclone">. The Go tool appends?go-get=1when resolving and reads that tag to find the real repo. - His nginx config branches on the query string: requests with
go-get=1get the static HTML, requests without it get 301-redirected to the actual repo — so the vanity domain stays useful for humans clicking a link.
The post is short and the config is copy-pasteable, which is the right shape for this kind of advice. What makes it worth reading is the argument underneath: a convenience nobody consciously chose quietly becomes a migration blocker, and the mitigation costs a few lines of nginx if you do it up front. Cambridge’s recommendation is that every commercial Go team namespace internal libraries under its own domain.
The three-hosting-services anecdote is the whole thesis in one image — an architectural decision that was never actually made, showing up as a recurring invoice.