10 - Packages and Organizing Code

📋 Jump to Takeaways

All 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 myapp

This creates a go.mod file:

module myapp

go 1.24

The module name is how your packages reference each other.

Creating a Package

myapp/
  go.mod
  main.go
  mathutil/
    mathutil.go

In 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() { }     // unexported

This 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, Sum

stats.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 name creates a module (project)
  • A package is a folder of .go files sharing the same package declaration
  • 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
  • main is the entry point. Everything else is a library that main imports

📝 Ready to test your knowledge?

Answer the quiz below to mark this lesson complete.

© 2026 ByteLearn.dev. Free courses for developers. · Privacy