10 - Packages and Organizing Code
📋 Jump to TakeawaysAll your code has been in one file. That works for small programs, but as code grows one file becomes hard to navigate. Packages let you split code into separate files and folders. Each package handles one responsibility.
What Is a Package?
Every Go file starts with package something. Files in the same directory that share the same package name can see each other's code. That's a package.
You've been using package main the whole time. main is special, it's the entry point. All other packages are libraries that main imports.
Setting Up a Module
Before you can create packages, you need a module. Create a folder for your project and run go mod init inside it:
mkdir myapp
cd myapp
go mod init myappThis creates a go.mod file:
module myapp
go 1.24The module name is how your packages reference each other.
Creating a Package
myapp/
go.mod
main.go
mathutil/
mathutil.goIn mathutil/mathutil.go:
package mathutil
func Min(a, b int) int {
if a < b {
return a
}
return b
}
func Max(a, b int) int {
if a > b {
return a
}
return b
}
func Clamp(value, low, high int) int {
return Max(low, Min(value, high))
}The package name matches the folder name. Every function starts with an uppercase letter to be visible outside the package.
Exported vs Unexported
If a name starts with an uppercase letter, it's exported (visible to other packages). Lowercase means unexported (private):
type Player struct { } // exported
type helper struct { } // unexported
func Calculate() { } // exported
func validate() { } // unexportedThis applies to struct fields too:
type Config struct {
Name string // exported
secret string // unexported
}No keywords like public or private. Just the first letter.
Importing Your Package
package main
import (
"fmt"
"myapp/mathutil"
)
func main() {
fmt.Println(mathutil.Min(3, 7)) // 3
fmt.Println(mathutil.Clamp(150, 0, 100)) // 100
}The import path is "myapp/mathutil", module name followed by folder name.
Standard Library Packages
You've been using these the whole time:
import (
"fmt" // printing and formatting
"os" // file operations
"strconv" // string conversions
"strings" // string manipulation
"errors" // creating errors
"math" // math functions
"sort" // sorting
)All built into Go. No installation needed.
Multiple Files in a Package
A package can have multiple files sharing the same package declaration:
myapp/
mathutil/
mathutil.go // Min, Max, Clamp
stats.go // Average, Sumstats.go:
package mathutil
func Sum(nums []int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}
func Average(nums []int) float64 {
if len(nums) == 0 {
return 0
}
return float64(Sum(nums)) / float64(len(nums))
}Both files are package mathutil. They can see each other's functions. From main.go, you still import "myapp/mathutil".
Key Takeaways
go mod init namecreates a module (project)- A package is a folder of
.gofiles sharing the samepackagedeclaration - Uppercase names are exported (public). Lowercase names are unexported (private)
- Import your own packages with
"modulename/packagename" - Multiple files in the same folder share the same package and can see each other's code
- Standard library packages (
fmt,os,strings,strconv) are always available - Organize code by responsibility, one package per concern
mainis the entry point. Everything else is a library thatmainimports