{"id":1118,"date":"2026-08-18T05:13:11","date_gmt":"2026-08-18T05:13:11","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/?p=1118"},"modified":"2026-08-18T05:13:12","modified_gmt":"2026-08-18T05:13:12","slug":"go-tutorials-15-minute-lab-dependency-management-with-go-modules","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/go-tutorials-15-minute-lab-dependency-management-with-go-modules\/","title":{"rendered":"Go Tutorials: 15-Minute Lab: Dependency Management with Go Modules"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Goal<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In this quick lab, you will experience the most important Go Modules concepts:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>import<\/code>\u00a0\u2014 use a package in Go source code<\/li>\n\n\n\n<li><code>require<\/code>\u00a0\u2014 record the module\/version in\u00a0<code>go.mod<\/code><\/li>\n\n\n\n<li>Module cache \u2014 find where Go downloaded the dependency<\/li>\n\n\n\n<li><code>go.sum<\/code>\u00a0\u2014 verify downloaded module content<\/li>\n\n\n\n<li>Version management \u2014 inspect and pin a dependency version<\/li>\n\n\n\n<li><code>replace<\/code>\u00a0\u2014 understand how a module can be redirected to another location<\/li>\n\n\n\n<li>Essential Go module commands<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Estimated time:<\/strong>&nbsp;15 minutes<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1. Check Go and Create the Module \u2014 2 minutes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Check Go:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go version\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Create the lab project:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir go-modules-lab\ncd go-modules-lab\ngo mod init example.com\/go-modules-lab\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Inspect the generated file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module example.com\/go-modules-lab\n\ngo 1.24\n<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Your Go version may be different.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">What happened?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>go mod init<\/code>&nbsp;created&nbsp;<code>go.mod<\/code>, which identifies this project as a Go module.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Import an External Package \u2014 3 minutes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create&nbsp;<code>main.go<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport (\n    \"fmt\"\n\n    \"github.com\/google\/uuid\"\n)\n\nfunc main() {\n    id := uuid.New()\n    fmt.Println(\"Generated ID:\", id)\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Notice this line:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import \"github.com\/google\/uuid\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">An&nbsp;<strong>import<\/strong>&nbsp;appears in Go source code. It tells the compiler that this package is used by the program.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now synchronize dependencies:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go mod tidy\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run the application:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go run .\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Generated ID: 550e8400-e29b-41d4-a716-446655440000\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The UUID will be different each time.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3. See How&nbsp;<code>import<\/code>&nbsp;Becomes&nbsp;<code>require<\/code>&nbsp;\u2014 2 minutes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Inspect&nbsp;<code>go.mod<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should see an entry similar to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module example.com\/go-modules-lab\n\ngo 1.24\n\nrequire github.com\/google\/uuid v1.6.0\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Import vs. Require<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Item<\/th><th class=\"has-text-align-left\" data-align=\"left\">Location<\/th><th class=\"has-text-align-left\" data-align=\"left\">Meaning<\/th><\/tr><\/thead><tbody><tr><td><code>import<\/code><\/td><td><code>.go<\/code>&nbsp;source file<\/td><td>This code uses a package<\/td><\/tr><tr><td><code>require<\/code><\/td><td><code>go.mod<\/code><\/td><td>This module needs a particular module version<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">In this example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import \"github.com\/google\/uuid\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">causes Go tooling to record the providing module in&nbsp;<code>go.mod<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>require github.com\/google\/uuid v1.6.0\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Usually, let Go commands such as&nbsp;<code>go get<\/code>&nbsp;and&nbsp;<code>go mod tidy<\/code>&nbsp;manage dependency requirements instead of manually editing versions.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Find Where Go Downloaded the Module \u2014 2 minutes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Display the module cache location:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go env GOMODCACHE\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A common location is similar to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/home\/student\/go\/pkg\/mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The default module cache is normally under:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$GOPATH\/pkg\/mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check your GOPATH:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go env GOPATH\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now ask Go for the exact directory of the downloaded UUID module:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go list -m -f '{{.Dir}}' github.com\/google\/uuid\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/home\/student\/go\/pkg\/mod\/github.com\/google\/uuid@v1.6.0\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Important<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Do not edit files inside the module cache. Go manages this directory.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To see how Go is configured to obtain modules, run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go env GOPROXY\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You may see something similar to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;proxy.golang.org,direct\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">5. Inspect&nbsp;<code>go.sum<\/code>&nbsp;and the Dependency Version \u2014 2 minutes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Inspect the checksum file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat go.sum\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You will see entries similar to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>github.com\/google\/uuid v1.6.0 h1:...\ngithub.com\/google\/uuid v1.6.0\/go.mod h1:...\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>go.sum<\/code>&nbsp;records cryptographic hashes used by Go to verify module content.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Both&nbsp;<code>go.mod<\/code>&nbsp;and&nbsp;<code>go.sum<\/code>&nbsp;should normally be committed with your project.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">See modules selected for the build:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go list -m all\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">See available versions of the UUID module:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go list -m -versions github.com\/google\/uuid\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Pin or change to a specific version:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go get github.com\/google\/uuid@v1.6.0\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then synchronize:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go mod tidy\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">6. Understand&nbsp;<code>replace<\/code>&nbsp;\u2014 2 minutes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A&nbsp;<code>replace<\/code>&nbsp;directive tells Go to use module code from another location instead of the normally resolved module source.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example&nbsp;<code>go.mod<\/code>&nbsp;syntax:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>require example.com\/sharedlib v0.0.0\n\nreplace example.com\/sharedlib =&gt; ..\/sharedlib\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is useful when developing two local modules together.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The application still imports the original module path:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import \"example.com\/sharedlib\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It does&nbsp;<strong>not<\/strong>&nbsp;change to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import \"..\/sharedlib\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can create a replacement directive with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go mod edit -replace=example.com\/sharedlib=..\/sharedlib\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">View the result:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Remove the demonstration directive afterward:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go mod edit -dropreplace=example.com\/sharedlib\n<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">A&nbsp;<code>replace<\/code>&nbsp;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.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">7. Essential Go Module Commands \u2014 2 minutes<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Command<\/th><th class=\"has-text-align-left\" data-align=\"left\">Purpose<\/th><\/tr><\/thead><tbody><tr><td><code>go mod init example.com\/app<\/code><\/td><td>Create a new module<\/td><\/tr><tr><td><code>go mod tidy<\/code><\/td><td>Add missing and remove unused requirements<\/td><\/tr><tr><td><code>go get module@version<\/code><\/td><td>Add, upgrade, or downgrade a dependency<\/td><\/tr><tr><td><code>go list -m all<\/code><\/td><td>List modules in the build list<\/td><\/tr><tr><td><code>go list -m -versions module<\/code><\/td><td>Show known versions of a module<\/td><\/tr><tr><td><code>go mod why -m module<\/code><\/td><td>Explain why a module is needed<\/td><\/tr><tr><td><code>go mod graph<\/code><\/td><td>Show the module dependency graph<\/td><\/tr><tr><td><code>go mod download<\/code><\/td><td>Download modules to the module cache<\/td><\/tr><tr><td><code>go mod verify<\/code><\/td><td>Verify cached module content against recorded hashes<\/td><\/tr><tr><td><code>go env GOMODCACHE<\/code><\/td><td>Show downloaded-module cache location<\/td><\/tr><tr><td><code>go env GOPROXY<\/code><\/td><td>Show module download\/proxy configuration<\/td><\/tr><tr><td><code>go clean -modcache<\/code><\/td><td>Remove the entire downloaded module cache<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Try these three now:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go mod why -m github.com\/google\/uuid\ngo mod verify\ngo list -m all\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Final Mental Model<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>main.go\n  |\n  | import \"github.com\/google\/uuid\"\n  v\ngo mod tidy \/ go get\n  |\n  +----&gt; go.mod\n  |       require github.com\/google\/uuid v1.6.0\n  |\n  +----&gt; go.sum\n  |       dependency checksums\n  |\n  +----&gt; GOMODCACHE\n          downloaded module source\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With a replacement:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import example.com\/sharedlib\n          |\n          v\nrequire example.com\/sharedlib ...\n          |\n          v\nreplace example.com\/sharedlib =&gt; ..\/sharedlib\n                                  |\n                                  v\n                           local module source\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Final Check<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Your project should contain:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go-modules-lab\/\n\u251c\u2500\u2500 go.mod\n\u251c\u2500\u2500 go.sum\n\u2514\u2500\u2500 main.go\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go mod tidy\ngo mod verify\ngo run .\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the application runs successfully, the lab is complete.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What You Experienced<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You now understand the core dependency flow:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>IMPORT  -&gt; package used by source code\nREQUIRE -&gt; module\/version recorded in go.mod\nDOWNLOAD -&gt; module stored in GOMODCACHE\nGO.SUM -&gt; verifies downloaded content\nREPLACE -&gt; redirects a module to another source\/location\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Lab complete.<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Goal In this quick lab, you will experience the most important Go Modules concepts: Estimated time:&nbsp;15 minutes 1. Check Go and Create the Module \u2014 2 minutes&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1118","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1118","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=1118"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1118\/revisions"}],"predecessor-version":[{"id":1119,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1118\/revisions\/1119"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=1118"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=1118"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=1118"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}