Go Modules is the standard dependency management mechanism introduced in Go 1.11+. The main files are go.mod (which defines the minimum dependencies and their versions) and go.sum (which ensures integrity through hashes).
To add a dependency, use:
go get github.com/pkg/errors@v0.9.1
To update dependencies:
go get -u ./... go mod tidy # remove unused
Go supports semantic versioning (semver), and dependencies are tightly locked: the project is reproducible, and the build is deterministic. However, keep in mind:
What happens if you delete the go.sum file and run the go build command, and why is it dangerous?
Many think that Go simply rebuilds the dependencies from scratch. But the go.sum file contains hashes of all used modules and protects against tampering (supply-chain attack). If it is deleted,
at the next build, Go will download the dependencies again, recreate the file, but if the dependency repository has been altered by a malicious actor — the protection is broken! Code substitution in production is possible.
Story
On a large project, the repository transitioned from vendoring to go modules, but they forgot to lock the versions. A month later, updates to third-party packages broke compatibility, making it impossible to build the old branch — the code lost reproducibility.
Story
In another project, a developer accidentally deleted go.sum. After restarting, the team noticed that some dependencies had changed, causing bugs related to minor version incompatibility — this resulted in a rollback several days back.
Story
Using replace paths for local directories (replace ... = ../some/library) was not removed before deployment — in the CI/CD pipeline, the build failed because the external system did not have access to local files, and production became "pinned" to an incorrect version.