Knaph

Packages, Modules, and Testing54 of 621 min read

Packages

Every Go file so far has started with package main. Time to see what that first line actually controls, and how real projects are organized beyond a single file.

Packages: Go's unit of code organization

Every .go file belongs to a package, declared on its first line. Files in the same directory must belong to the same package, and that directory is the package — Go has no separate "module" keyword for grouping files the way some languages do; the folder structure does the job.

// file: shapes/rectangle.go
package shapes
 
type Rectangle struct {
	Width, Height float64
}
 
func (r Rectangle) Area() float64 {
	return r.Width * r.Height
}
Go

Another file, shapes/circle.go, would also start with package shapes and can use Rectangle directly — no import needed for files in the same package.

Only package main produces a runnable program; every other package name marks a library that other code imports. Recall from the very first lesson: only capitalized names (Rectangle, Area) are visible outside the package — that's the mechanism controlling what a package exposes to its importers.

Importing your own package

// file: main.go
package main
 
import (
	"fmt"
	"myproject/shapes"
)
 
func main() {
	r := shapes.Rectangle{Width: 3, Height: 4}
	fmt.Println(r.Area())
}
Go

The import path (myproject/shapes) isn't a filesystem path — it's the module path defined in go.mod, plus the subdirectory. Which brings us to modules, next.

Sign in to track your progress through this course.

Ask an AI

Open a ready-made prompt in ChatGPT or Claude — just press Enter.