Skip to content
All essays
CraftMarch 19, 202411 min

Go Modules and Package Management

Master Go modules for dependency management and versioning

Ü
Ümit Uz
Mobile & Full Stack Developer

Go modules are Go's dependency management system, introduced in Go 1.11. They provide official support for versioning and dependency resolution, making it easy to manage external dependencies in your projects.

What Are Go Modules?

A Go module is a collection of Go packages that have a common go.mod file.

Module Definition

The go.mod file defines the module path and dependencies:

go
module github.com/user/myproject

go 1.21

require (
    github.com/gorilla/mux v1.8.0
    github.com/stretchr/testify v1.8.4
)

Benefits

  • Official dependency management
  • Semantic versioning support
  • Reproducible builds
  • No need for GOPATH
  • Direct and transitive dependency versioning

Creating a Module

Initialize a new module with go mod init.

Basic Initialization

bash
mkdir myproject
cd myproject
go mod init github.com/user/myproject

This creates go.mod:

go
module github.com/user/myproject

go 1.21

Module Path

The module path is typically the repository location:

bash
# For GitHub
go mod init github.com/username/myproject

# For GitLab
go mod init gitlab.com/username/myproject

# For local development
go mod init myproject

Adding Dependencies

Go automatically adds dependencies when you import them.

Automatic Addition

go
package main

import "github.com/gorilla/mux"

func main() {
    r := mux.NewRouter()
}

Run go build or go mod tidy:

bash
go build

Go updates go.mod and go.sum automatically.

Manual Addition

bash
go get github.com/gorilla/mux@latest
go get github.com/gorilla/mux@v1.8.0

Specific Versions

bash
# Specific version
go get github.com/pkg/errors@v0.9.1

# Branch or commit
go get github.com/pkg/errors@master
go get github.com/pkg/errors@abc123def

go.mod File Structure

Understanding go.mod is crucial for dependency management.

Module Declaration

go
module github.com/user/project

Defines the module's import path.

Go Version

go
go 1.21

Minimum Go version required.

Require Directive

go
require (
    github.com/gorilla/mux v1.8.0
    github.com/stretchr/testify v1.8.4
)

Lists direct dependencies.

Indirect Dependencies

go
require github.com/davecgh/go-spew v1.1.1 // indirect

Transitive dependencies not directly imported.

Exclude Directive

go
exclude github.com/bad/module v1.0.0

Excludes specific problematic versions.

Replace Directive

go
replace github.com/old/module => github.com/new/module v1.0.0

Replaces a module with another.

Local Replace

go
replace github.com/user/project => ../project

Useful for local development.

go.sum File

go.sum contains cryptographic checksums for dependency verification.

Purpose

github.com/gorilla/mux v1.8.0 h1:x...
github.com/gorilla/mux v1.8.0/go.mod h1:...

Ensures reproducible builds and security.

Don't Edit Manually

go.sum is maintained by Go tooling.

Managing Dependencies

Commands for managing your dependencies.

go mod tidy

Clean up dependencies:

bash
go mod tidy
  • Adds missing dependencies
  • Removes unused dependencies
  • Updates go.mod and go.sum

go mod verify

Verify dependencies:

bash
go mod verify

Checks that dependencies haven't been modified.

go mod download

Download dependencies:

bash
go mod download

Downloads all dependencies to module cache.

go mod why

Explain why a dependency is needed:

bash
go mod why github.com/pkg/errors

Shows dependency chain.

go list

List dependencies:

bash
# All dependencies
go list -m all

# Specific module
go list -m github.com/gorilla/mux

Versioning

Go modules use semantic versioning.

Version Format

Versions follow semantic versioning: vX.Y.Z

  • Major (X): Incompatible API changes
  • Minor (Y): New features, backwards compatible
  • Patch (Z): Bug fixes, backwards compatible

Pre-release Versions

bash
go get github.com/user/module@v1.0.0-beta
go get github.com/user/module@v1.0.0-rc.1

Pseudo-Versions

For untagged commits:

bash
v1.0.0-20230101234567-abc123def

Updating Dependencies

Keep dependencies up-to-date.

Update All

bash
go get -u ./...
go mod tidy

Updates to latest minor/patch versions.

Update Specific

bash
go get -u github.com/gorilla/mux

Patch Updates Only

bash
go get -u=patch github.com/gorilla/mux

Won't update to new minor/major versions.

Major Version Upgrades

bash
go get github.com/user/module@v2

Note: Major version changes often require path changes.

Major Versions

Go modules use module path for major versions.

Major Version 2+

go
module github.com/user/module/v2

require github.com/user/module/v2 v2.0.0

The /v2 suffix is required.

Importing Major Versions

go
import "github.com/user/module/v2"

Multiple Major Versions

go
require (
    github.com/user/module v1.5.0
    github.com/user/module/v2 v2.0.0
)

Vendoring

Vendor dependencies in your project.

Vendor Dependencies

bash
go mod vendor

Creates vendor/ directory with all dependencies.

Use Vendor

bash
go build -mod=vendor

Builds from vendor directory.

Private Repositories

Use private Git repositories as modules.

Authentication

Configure Git credentials:

bash
git config --global url."https://username:token@github.com/".insteadOf "https://github.com/"

Or use SSH:

bash
git config --global url."git@github.com:".insteadOf "https://github.com/"

GOPRIVATE Environment

bash
export GOPRIVATE=github.com/mycompany/*

Bypasses proxy and checksum database for private repos.

Module Proxy

Go uses a public module proxy by default.

Default Proxy

https://proxy.golang.org

Checksum Database

https://sum.golang.org

Verifies module integrity.

Custom Proxy

bash
export GOPROXY=https://goproxy.io,direct
export GOPROXY=https://goproxy.cn,direct

Direct Mode

bash
export GOPROXY=direct

Bypasses proxy, connects directly.

Workspace Mode

Work with multiple modules together.

go.work File

bash
go work init
go work use ./module1
go work use ./module2

Creates go.work:

go
go 1.21

use (
    ./module1
    ./module2
)

Benefits

  • Edit multiple modules simultaneously
  • Replace with local directories automatically
  • Test changes across modules

Common Patterns

Minimal go.mod

go
module github.com/user/project

go 1.21

Let Go manage dependencies automatically.

Development Replace

go
module github.com/user/project

go 1.21

replace github.com/user/project => ../project

Use local version during development.

Testing Forks

go
replace github.com/original/repo => github.com/fork/repo v1.0.0

Test your fork before contributing.

Best Practices

  1. 1Always commit go.mod and go.sum
  2. 2Use semantic versioning
  3. 3Keep dependencies updated
  4. 4Run go mod tidy regularly
  5. 5Review changes before committing
  6. 6Use workspace mode for multi-module projects
  7. 7Pin critical dependencies
  8. 8Use GOPRIVATE for private repos

Common Issues

Dependency Conflicts

bash
go: github.com/conflicting/module@v1.0.0 requires
    github.com/other/module@v2.0.0

Solution: Use replace directive.

Import Version Mismatch

go
import "github.com/user/module" // Uses v1

When go.mod specifies v2:

go
import "github.com/user/module/v2" // Correct

Outdated go.sum

bash
go mod verify
go mod download

Debugging Modules

View Dependency Graph

bash
go mod graph | grep github.com/user/module

Check Module Info

bash
go mod edit -require github.com/user/module@v1.0.0
go list -m -json github.com/user/module

Fix Corrupted go.sum

bash
go mod download
go mod verify

Performance Tips

Module Cache

Go caches modules locally:

bash
# Clear cache
go clean -modcache

Parallel Downloads

Downloads are parallel by default.

Conclusion

Go modules provide a robust, official solution for dependency management in Go. They combine simplicity with powerful features like semantic versioning, reproducible builds, and workspace mode.

Master Go modules, and you'll manage dependencies confidently, whether working on small projects or large multi-module codebases. The tooling is designed to get out of your way while ensuring your builds are reproducible and secure.

Practice with go mod commands, understand semantic versioning, and leverage workspace mode for complex projects. Go modules are an essential part of modern Go development.

Enjoyed this essay? Share it.

Related essays

Next essay
React Server Components Guide