100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Go

Packages and Go Modules

Learn how Go organizes code into packages and manages dependencies with go.mod using the modules system.

Packages & ToolingBeginner9 min readJul 8, 2026
Analogies

Introduction

Every Go source file belongs to a package, declared with a package clause at the top of the file. Packages are the primary unit of code organization and reuse in Go: they group related functionality, control what is visible to other code, and form the building blocks that Go Modules assemble into dependency graphs. An executable program is built from a package main containing a func main() entry point, while reusable libraries use any other package name.

🏏

Cricket analogy: Like every player belonging to a specific team roster declared at signing, the national XI (package main) must have a designated captain (func main()) to take the field, while domestic squads (library packages) exist to be drawn upon.

Syntax

go
// file: mathutil/add.go
package mathutil

// Add is exported (capitalized) so other packages can call it.
func Add(a, b int) int {
    return a + b
}

// subtract is unexported; only visible inside package mathutil.
func subtract(a, b int) int {
    return a - b
}

Explanation

Go's export rule is based purely on capitalization: identifiers (functions, types, variables, constants, struct fields) starting with an uppercase letter are exported and accessible from other packages; lowercase identifiers are unexported and stay private to their package. A module is one or more packages tracked together with a go.mod file, which records the module's import path and its dependencies. Running go mod init example.com/myapp creates the go.mod file, go get package@version adds or upgrades a dependency, and go mod tidy adds missing requirements and removes unused ones. A companion go.sum file stores cryptographic checksums of dependency contents to ensure reproducible, tamper-evident builds. Modules replaced the older GOPATH-based workflow starting in Go 1.11, removing the requirement that code live in a specific workspace directory.

🏏

Cricket analogy: Like a team's official squad list where capitalized names (exported) are eligible for international selection while lowercase reserve names stay domestic-only, and a signed contract (go.mod) records the roster and imported player agreements, with a verification ledger (go.sum) confirming no tampering.

Example

go
// go.mod
module example.com/greeter

go 1.21

require github.com/google/uuid v1.3.0

// file: main.go
package main

import (
    "fmt"

    "example.com/greeter/mathutil"
)

func main() {
    sum := mathutil.Add(2, 3)
    fmt.Println("2 + 3 =", sum)
}

Output

bash
$ go mod init example.com/greeter
$ go mod tidy
$ go run main.go
2 + 3 = 5

Key Takeaways

  • Every .go file must start with a package declaration; package main plus func main() defines an executable's entry point.
  • Capitalized identifiers are exported (public); lowercase identifiers are unexported (package-private).
  • go.mod defines the module path, Go version, and dependency requirements; go.sum stores checksums for verification.
  • go mod init creates a new module; go get adds/upgrades dependencies; go mod tidy synchronizes go.mod with actual imports.
  • Modules (Go 1.11+) replaced GOPATH, letting projects live anywhere on disk and use semantic-versioned dependencies.

Practice what you learned

Was this page helpful?

Topics covered

#Go#GoProgrammingStudyNotes#Programming#PackagesAndGoModules#Packages#Modules#Syntax#Explanation#StudyNotes#SkillVeris