Go (Golang) Tutorial 0/45 lessons ~6 min read Lesson 20

    Modules

    Go modules are the official dependency management system introduced in Go 1.11 and default in 1.16+.

    Course progress0%
    Focus
    10 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    Go modules are the official dependency management system introduced in Go 1.11 and default in 1.16+. A module is defined by go.mod at the repo root, declaring the module path, Go version, and required dependencies with checksums in go.sum.

    Commands like go get, go mod tidy, and go mod vendor manage dependencies. Semantic import versioning (v2+ module path suffix) and retract directives handle breaking changes professionally.

    Every production Go repo uses modules — interviewers ask about MVS (Minimal Version Selection), go.sum integrity, and private module proxies.

    The story

    When Cloudflare open-sources a Go library, consumers add require github.com/cloudflare/cfssl v1.6.5 to their go.mod. Semantic versioning and the module proxy ensure reproducible builds — the same checksums in go.sum that CI verifies before deploying to production Kubernetes clusters.

    Module boundaries replace the old GOPATH workflow: each repo has its own go.mod, go get upgrades dependencies, and replace directives patch local forks during development.

    Understanding the topic

    Key concepts

    • go mod init module/path creates go.mod.
    • require block lists dependencies; go.sum stores cryptographic hashes.
    • go get package@version adds/updates dependency.
    • go mod tidy adds missing, removes unused modules.
    • Semantic versioning: v0/v1 in path; v2+ requires /v2 in module path.
    • GOPRIVATE bypasses proxy for internal modules.

    Step-by-step explanation

    1. go mod init sets module path (usually GitHub URL).
    2. Import third-party package — go mod tidy fetches and records.
    3. go build reads go.mod, downloads to module cache.
    4. proxy.golang.org serves public modules; sumdb verifies checksums.
    5. replace directive points to local fork for development.
    6. go work combines multiple modules in monorepo.

    Practical code example

    go.mod with require, retract awareness, and tidy workflow:

    go
    // go.mod
    module github.com/techlearningpro/payments
    go 1.22
    require (
    github.com/google/uuid v1.6.0
    github.com/stretchr/testify v1.9.0
    )
    // Run: go mod tidy
    // Run: go get github.com/google/uuid@v1.6.0
    // main.go
    package main
    import (
    "fmt"
    "github.com/google/uuid"
    )
    func main() {
    id := uuid.New()
    fmt.Println("payment id:", id)
    }

    Line-by-line code explanation

    • module github.com/acme/payments declares the module path at the top of go.mod.
    • go 1.22 sets the minimum language version for the module.
    • require github.com/lib/pq v1.10.9 pins a direct dependency with semver.
    • go.sum stores cryptographic checksums — commit it to prevent supply-chain tampering.
    • go get github.com/pkg/errors@v0.9.1 adds or upgrades a dependency and updates sums.
    • go mod tidy removes unused requires and adds missing ones — run before every commit.
    • replace github.com/x/y => ../local-y redirects imports to a local path during development.
    • go mod vendor copies dependencies into vendor/ for air-gapped or hermetic builds.

    Key takeaway: Commit go.sum — it prevents supply chain tampering. Use go mod tidy in CI. GOPRIVATE=github.com/myorg for private repos.

    Real-world use

    Where you'll use this in production

    • Pinning dependency versions for reproducible CI builds.
    • Monorepo with go.work linking api and worker modules.
    • Vendoring dependencies for air-gapped deployments.
    • Private module hosting on GitHub/GitLab with GOPRIVATE.

    Best practices

    • Run go mod tidy before every commit touching imports.
    • Commit go.mod and go.sum together.
    • Use semantic versioning tags for your published modules.
    • Set GOPRIVATE for internal module paths.
    • Review go get upgrades in dedicated PRs with test coverage.
    • Document minimum Go version in go.mod go directive.

    Common mistakes

    • Deleting go.sum entries manually — run go mod tidy instead.
    • Importing v2 module without /v2 in path — compile errors.
    • Not committing go.sum — CI builds fail or become insecure.
    • replace left in production go.mod pointing to local paths.
    • Using @latest in production without pinning in require.

    Advanced interview questions

    Q1Beginnergo.mod vs go.sum?
    go.mod declares module and deps; go.sum checksums every module version for integrity.
    Q2Beginnergo mod tidy purpose?
    Adds missing module requirements; removes unused ones; updates go.sum.
    Q3IntermediateMinimal Version Selection?
    Go selects minimum version satisfying all require constraints — reproducible builds.
    Q4IntermediateImport v2 breaking module?
    Module path must include /v2: import github.com/foo/bar/v2.
    Q5AdvancedManage private modules in enterprise.
    GOPRIVATE env; internal proxy (Athens); SSH/HTTPS auth; vendor for CI without network.

    Summary

    go.mod defines module path, Go version, and dependencies. go mod tidy keeps dependencies clean; commit go.sum always. v2+ modules require /v2 suffix in import path. GOPRIVATE and go.work support enterprise monorepos. Next lesson: goroutines — lightweight concurrency.

    Ready to mark this lesson complete?Track your journey across the entire course.