Go Tutorials: 15-Minute Lab: Dependency Management with Go Modules

Goal

In this quick lab, you will experience the most important Go Modules concepts:

  • import — use a package in Go source code
  • require — record the module/version in go.mod
  • Module cache — find where Go downloaded the dependency
  • go.sum — verify downloaded module content
  • Version management — inspect and pin a dependency version
  • replace — understand how a module can be redirected to another location
  • Essential Go module commands

Estimated time: 15 minutes


1. Check Go and Create the Module — 2 minutes

Check Go:

go version

Create the lab project:

mkdir go-modules-lab
cd go-modules-lab
go mod init example.com/go-modules-lab

Inspect the generated file:

cat go.mod

Example:

module example.com/go-modules-lab

go 1.24

Your Go version may be different.

What happened?

go mod init created go.mod, which identifies this project as a Go module.


2. Import an External Package — 3 minutes

Create main.go:

package main

import (
    "fmt"

    "github.com/google/uuid"
)

func main() {
    id := uuid.New()
    fmt.Println("Generated ID:", id)
}

Notice this line:

import "github.com/google/uuid"

An import appears in Go source code. It tells the compiler that this package is used by the program.

Now synchronize dependencies:

go mod tidy

Run the application:

go run .

Example output:

Generated ID: 550e8400-e29b-41d4-a716-446655440000

The UUID will be different each time.


3. See How import Becomes require — 2 minutes

Inspect go.mod:

cat go.mod

You should see an entry similar to:

module example.com/go-modules-lab

go 1.24

require github.com/google/uuid v1.6.0

Import vs. Require

ItemLocationMeaning
import.go source fileThis code uses a package
requirego.modThis module needs a particular module version

In this example:

import "github.com/google/uuid"

causes Go tooling to record the providing module in go.mod:

require github.com/google/uuid v1.6.0

Usually, let Go commands such as go get and go mod tidy manage dependency requirements instead of manually editing versions.


4. Find Where Go Downloaded the Module — 2 minutes

Display the module cache location:

go env GOMODCACHE

A common location is similar to:

/home/student/go/pkg/mod

The default module cache is normally under:

$GOPATH/pkg/mod

Check your GOPATH:

go env GOPATH

Now ask Go for the exact directory of the downloaded UUID module:

go list -m -f '{{.Dir}}' github.com/google/uuid

Example:

/home/student/go/pkg/mod/github.com/google/uuid@v1.6.0

Important

Do not edit files inside the module cache. Go manages this directory.

To see how Go is configured to obtain modules, run:

go env GOPROXY

You may see something similar to:

https://proxy.golang.org,direct

The module may therefore be obtained through a configured Go module proxy or directly from its version-control source, depending on the environment and module settings.


5. Inspect go.sum and the Dependency Version — 2 minutes

Inspect the checksum file:

cat go.sum

You will see entries similar to:

github.com/google/uuid v1.6.0 h1:...
github.com/google/uuid v1.6.0/go.mod h1:...

go.sum records cryptographic hashes used by Go to verify module content.

Both go.mod and go.sum should normally be committed with your project.

See modules selected for the build:

go list -m all

See available versions of the UUID module:

go list -m -versions github.com/google/uuid

Pin or change to a specific version:

go get github.com/google/uuid@v1.6.0

Then synchronize:

go mod tidy

6. Understand replace — 2 minutes

replace directive tells Go to use module code from another location instead of the normally resolved module source.

Example go.mod syntax:

require example.com/sharedlib v0.0.0

replace example.com/sharedlib => ../sharedlib

This is useful when developing two local modules together.

The application still imports the original module path:

import "example.com/sharedlib"

It does not change to:

import "../sharedlib"

You can create a replacement directive with:

go mod edit -replace=example.com/sharedlib=../sharedlib

View the result:

cat go.mod

Remove the demonstration directive afterward:

go mod edit -dropreplace=example.com/sharedlib

replace directive redirects a module; it does not by itself make an unused module a dependency. The module must also be required somewhere in the module graph for the replacement to affect the build.


7. Essential Go Module Commands — 2 minutes

CommandPurpose
go mod init example.com/appCreate a new module
go mod tidyAdd missing and remove unused requirements
go get module@versionAdd, upgrade, or downgrade a dependency
go list -m allList modules in the build list
go list -m -versions moduleShow known versions of a module
go mod why -m moduleExplain why a module is needed
go mod graphShow the module dependency graph
go mod downloadDownload modules to the module cache
go mod verifyVerify cached module content against recorded hashes
go env GOMODCACHEShow downloaded-module cache location
go env GOPROXYShow module download/proxy configuration
go clean -modcacheRemove the entire downloaded module cache

Try these three now:

go mod why -m github.com/google/uuid
go mod verify
go list -m all

Final Mental Model

main.go
  |
  | import "github.com/google/uuid"
  v
go mod tidy / go get
  |
  +----> go.mod
  |       require github.com/google/uuid v1.6.0
  |
  +----> go.sum
  |       dependency checksums
  |
  +----> GOMODCACHE
          downloaded module source

With a replacement:

import example.com/sharedlib
          |
          v
require example.com/sharedlib ...
          |
          v
replace example.com/sharedlib => ../sharedlib
                                  |
                                  v
                           local module source

Final Check

Your project should contain:

go-modules-lab/
├── go.mod
├── go.sum
└── main.go

Run:

go mod tidy
go mod verify
go run .

If the application runs successfully, the lab is complete.

What You Experienced

You now understand the core dependency flow:

IMPORT  -> package used by source code
REQUIRE -> module/version recorded in go.mod
DOWNLOAD -> module stored in GOMODCACHE
GO.SUM -> verifies downloaded content
REPLACE -> redirects a module to another source/location

Lab complete.

Related Posts

Kafka Master Tutorials Series: 7 Topics, Partitions, Consumers, Consumer Groups & Lag

Developer Planning Guide for Correct Mapping, Scaling, Reliability and Performance Audience: Developers, students, freshers, architects, platform engineersTraining context: Confluent Kafka ClusterGoal: Remove confusion around how Kafka Topics, Partitions, Producers, Consumers,…

Read More

Kafka Master Tutorials Series: 6 – Kafka Consumer Deep Dive

Consumer Groups, Parallelism, Offsets, Rebalancing, Failover, Consumption Patterns and Production Tuning Audience: Students and freshers with no previous Kafka experienceGoal: Start with “What is a consumer?” and finish with…

Read More

Redis Tutorials: A Complete Fundamental Turorials

From Fundamentals to Production-Grade Caching, Sessions, Pub/Sub, Counters, Locks and Failure Handling 1. What is Redis? Redis is a high-performance, primarily in-memory data store. The easiest mental…

Read More

Kafka Master Tutorials Series: 5 – Deep Dive Into Kafka Producers

From send() to Broker ACK: Keys, Partitions, Batching, Retries, Reliability, Latency and Performance Tuning Audience: Students and freshers with no prior Kafka experienceGoal: Build from producer fundamentals to production-grade Kafka producer…

Read More

Kafka Master Tutorials Series: 4 – Confluent Cloud Kafka — Production Checklist

1. Cluster Architecture Recommended architecture: 2. Capacity Planning Confluent recommends monitoring cluster load closely. Sustained load around 70–80% is a reason to consider adding CKUs, while above…

Read More

Kafka Master Tutorials Series: 3 -Capacity Planning in Confluent Cloud

1. What is Kafka Capacity Planning? Capacity planning means calculating how much Kafka capacity your application needs before production traffic arrives. In simple words: How big should…

Read More