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
}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())
}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.