Modules & Packages (go mod)
Real Go programs span many files and pull in third-party libraries. This lesson covers how Go organizes code: packages (folders of related code) and modules (versioned collections managed by go mod ). By the end you'll structure a project, export names across packages, and add dependencies.
Learn Modules & Packages (go mod) in our free Go course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick recall.
Part of the free Go course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
📊 Modules vs Packages
Concept
Is
Defined by
package
A folder of .go files sharing a name
package X at top of file
module
A versioned group of packages
go.mod file
import path
How others refer to your package
module path + folder
One module contains one or more packages. The package you run lives in package main and has a func main() ; everything else is a library package imported by others.
1️⃣ Packages & Exported Names
Every Go file begins with package X , and all files in one folder must share that name. The rule for visibility is delightfully simple: a name starting with a capital letter is exported (visible to other packages); a lowercase name is private to its package. No public / private keywords — just capitalization.
Another package imports it by its import path (module path + folder) and calls only its exported names.
Your turn. Rename the function so it can be called from outside its package.
2️⃣ The go.mod File
A module is declared by a go.mod file at the project root. You create it once with go mod init <path> . It records the module's import path, the minimum Go version, and every dependency with its exact version — so anyone who clones your project gets the same builds.
3️⃣ The go Command Workflow
Day to day you'll use a handful of commands. go mod init starts a module, go get adds a dependency, go mod tidy syncs go.mod with what your code actually imports, and go run . builds and runs the current package.
4️⃣ Using a Third-Party Package
Once a dependency is in go.mod , importing and using it is no different from the standard library — Go fetches it from the source repository and caches it. Below we generate a UUID with a popular library after a single go get .
🧩 Reorder Challenge
These are the steps to start a project and run it with a dependency. Put them in the correct order:
B, D, C, E, A. Initialize the module first (it must exist before anything else), add the dependency, write the code that uses it, run go mod tidy to reconcile go.mod , then run. In practice go get and writing code interleave, but init is always first and run last.
🧠 Quick Recall
No. format is lowercase, so it's unexported — visible only inside package util . Rename it Format to call it from another package.
go mod init example.com/myapp — this writes a go.mod declaring the module path. Run it once at the project root.
It adds any imports your code uses but go.mod is missing, and removes dependencies no longer imported. It keeps go.mod / go.sum in sync with the actual code.
Pro Tips
- 💡 Pick a real-looking module path like github.com/you/project , even for local work — it avoids clashes and is ready to publish later.
- 💡 Run go mod tidy before committing. It keeps go.mod and go.sum honest and reproducible.
- 💡 Commit go.sum . It pins cryptographic checksums of dependencies so builds are verifiable and tamper-evident.
- 💡 One package per folder, named after its purpose. Keep package names short, lowercase, and free of underscores.
Common Errors (and the fix)
- "go.mod file not found in current directory or any parent directory" — you're not inside a module. Run go mod init <path> first.
- "undefined: greeting.secret" — you tried to use an unexported (lowercase) name from another package. Only capitalized names are visible.
- "found packages X and Y in same dir" — two files in one folder declare different package names. All files in a folder must share one package name.
- "missing go.sum entry" — a dependency isn't recorded. Run go mod tidy (or go mod download ) to fetch and record it.
- "package example.com/app/foo is not in std" — the import path doesn't match your module path plus folder. Check the path in go.mod and the folder name.
Frequently Asked Questions
Q: What's the difference between a package and a module?
A package is a single folder of related code. A module is a versioned bundle of one or more packages with a go.mod file and an import path. You import packages; you version and distribute modules.
Purely by capitalization. A capitalized identifier (function, type, field, constant) is exported and visible to importers; a lowercase one is package-private. This applies to struct fields too — which is why JSON only sees capitalized fields.
Only the first time you fetch a dependency. Go caches downloaded modules locally, so subsequent builds work offline. go.sum verifies that cached copies haven't changed.
Run go get example.com/dep@latest (or a specific version like @v1.5.0 ), then go mod tidy . Go updates go.mod and go.sum to the chosen version.
Mini-Challenge: Structure a Project
No blanks — a design brief. Sketch the files and commands for a small two-package project, deciding which names must be exported. This mirrors how every real Go repository is laid out.
🎉 Lesson Complete!
- ✅ A package is a folder of files sharing one package name
- ✅ Capitalized names are exported; lowercase names are package-private
- ✅ A module is declared by go.mod , created with go mod init
- ✅ Import your own packages by module path + folder
- ✅ Add dependencies with go get , reconcile with go mod tidy
- ✅ go.sum pins versions for reproducible, verifiable builds
- ✅ Next lesson: Checkpoint — build a small program
Practice quiz
What is a Go package?
- A single file
- A folder of files sharing one package name
- A compiled binary
- A remote server
Answer: A folder of files sharing one package name. A package is a directory of source files that all declare the same package name.
How is a name made exported (visible outside its package)?
- A keyword 'export'
- A capitalized first letter
- An export tag
- Being in main
Answer: A capitalized first letter. Capitalized identifiers are exported; lowercase ones are package-private.
What file declares a Go module?
- package.json
- go.mod
- module.go
- Gopkg.toml
Answer: go.mod. go.mod declares the module path and its dependencies.
Which command creates a new module?
- go new
- go mod init
- go create
- go module
Answer: go mod init. go mod init <path> creates the go.mod file for a new module.
Which command adds a dependency to your module?
- go add
- go install
- go get
- go fetch
Answer: go get. go get adds (or upgrades) a dependency and records it in go.mod.
Which command removes unused dependencies and adds missing ones?
- go clean
- go mod tidy
- go fix
- go vet
Answer: go mod tidy. go mod tidy reconciles go.mod/go.sum with the imports your code actually uses.
What is the purpose of go.sum?
- Lists TODOs
- Pins and verifies dependency checksums
- Stores secrets
- Configures the editor
Answer: Pins and verifies dependency checksums. go.sum records cryptographic checksums so builds are reproducible and verifiable.
How do you import one of your own packages?
- By file path
- By module path plus the package folder
- By package name only
- You cannot
Answer: By module path plus the package folder. Internal packages are imported using the module path joined with the subfolder.
Which package name marks an executable program?
- package app
- package main
- package exe
- package run
Answer: package main. package main (with func main) builds an executable; other names build libraries.
Can a lowercase function from another package be called directly?
- Yes, always
- No, it is unexported and package-private
- Only in tests
- Only with reflection
Answer: No, it is unexported and package-private. Lowercase names are unexported, so they are not accessible from outside their package.
Continue this course
- Previous: Working with JSON (Marshal/Unmarshal)
- Next: Checkpoint: A Small Program