# Packages and Modules

Course: [Go](https://www.devtutorials.ai/learn/go) · Section: Packages and Modules
Source: https://www.devtutorials.ai/learn/go/packages/packages-and-modules

> How Go organises code into packages, exported and unexported names, the four kinds of import, Go modules with go.mod, go.sum and go mod tidy, managing dependencies, and the key standard packages.

## What Are Packages?

**Package** = a folder of Go files that work together and share one name.

- Every Go file starts with `package name`.
- All files in one folder belong to the **same** package.
- A package can use code from other packages by **importing** them.

You have already used packages:

- `fmt` for printing
- `strconv` for turning text into numbers
- `main`, the package for your own program

**Simple lesson:** a package is a named group of Go files that you can reuse.

### A Real-World Example

Think of the school library.

- Books are kept on shelves by subject: **Maths**, **Science**, **Stories**.
- Each shelf has a label.
- To read a maths book, you go to the Maths shelf and take one.
- Some books are **for reference only**. You can read them inside, but not take them out.

Now the mapping:

- **A shelf** = a package.
- **Going to a shelf** = `import`.
- **Taking a book** = using a name like `strings.ToUpper`.
- **Reference-only books** = **unexported** names that stay inside the package.

Two words in this lesson sound alike:

- **Package** = one folder of Go code.
- **Module** = a whole project: one or more packages, with a `go.mod` file at the top.

You met `go.mod` in **Introduction to Go**.

## What You Will Learn

In this lesson, you will learn:

1. What packages are, how they are laid out and named.
2. How exported and unexported names work.
3. How to import packages, with aliases, blank imports and dot imports.
4. How Go modules work: `go mod init`, `go mod tidy`, `go.mod` and `go.sum`.
5. How to install, update and remove modules.
6. The most useful packages in Go's standard library.

## Package Fundamentals

### Package Structure

A small school project could look like this:

```text
school/
├── go.mod
├── main.go            package main
└── marks/
    ├── marks.go       package marks
    └── grade.go       package marks
```

- The `school` folder is the **module**. `go.mod` sits at its top.
- `main.go` is in package `main`. It makes the program.
- The `marks` folder is its own package, named `marks`.
- Both files in `marks/` start with `package marks`.

### package main vs Other Packages

### Package Naming Conventions

- Use **short, lowercase, single words**: `marks`, `report`, `strings`.
- No underscores or capitals: not `Marks_Utils`.
- Name the package after what it **gives**, not what it **holds**: `report`, not `utils`.
- The folder name and the package name are usually the same.

### Exported Identifiers

**Exported** = a name that starts with a **capital letter**. Other packages can use it.

**Unexported** = a name that starts with a **small letter**. Only its own package can use it.

```go
package marks

// Average is exported: other packages can call marks.Average.
func Average(list []int) float64 {
	return float64(total(list)) / float64(len(list))
}

// total is unexported: only code inside package marks can call it.
func total(list []int) int {
	sum := 0
	for _, m := range list {
		sum += m
	}
	return sum
}
```

- From `main`, you can write `marks.Average(...)`.
- `marks.total(...)` fails with `undefined: marks.total`, because it is not exported.
- This is why the standard library has `fmt.Println` with a capital `P`.

**Easy way to remember**

- **C**apital = **C**an be used outside.
- small = stays inside.

**Simple lesson:** a package is a folder with one name, and only Capitalised names can be used from outside it.

## Working with Packages

### Importing Packages

```go runnable title="Import several packages"
package main

import (
	"fmt"
	"math"
	"strings"
)

func main() {
	fmt.Println(strings.ToUpper("green valley"))
	fmt.Println(math.Sqrt(144))
}
```

```text
GREEN VALLEY
12
```

- Put each import on its own line inside `import ( )`.
- Use a name as `packageName.Name`: `strings.ToUpper`.
- The package name is the **last part** of the import path: `"math/rand"` is used as `rand`.

### The Ways to Import

### Package Aliases

```go runnable title="An alias for a package"
package main

import (
	"fmt"
	str "strings"
)

func main() {
	fmt.Println(str.Repeat("Go! ", 3))
}
```

```text
Go! Go! Go! 
```

### Blank Imports

**Blank import** = `import _ "path"`. It runs the package's set-up code, but you use none of its names.

```go runnable title="A blank import"
package main

import (
	"fmt"
	_ "image/png"
)

func main() {
	fmt.Println("PNG support is now registered")
}
```

```text
PNG support is now registered
```

- Without `_`, Go would refuse: `"image/png" imported and not used`.
- With `_`, the package sets itself up so other code can read PNG images.

### Dot Imports

**Dot import** = `import . "path"`. You use its names with no prefix.

```go runnable title="A dot import"
package main

import (
	"fmt"
	. "strconv"
)

func main() {
	fmt.Println(Itoa(2025) + " batch")
}
```

```text
2025 batch
```

- `Itoa` works without `strconv.` in front.
- A reader cannot tell where `Itoa` comes from. That is why dot imports are discouraged.

**Simple lesson:** import a package, then use its exported names as `package.Name`.

## Go Modules

**Module** = a Go project. It is a folder with a `go.mod` file and all the packages under it.

### go mod init

**`go mod init`** = create a new module in the current folder.

```bash
go mod init example.com/school
```

- `example.com/school` is the **module path**: the project's full name.
- For a project on GitHub, it is usually `github.com/your-name/school`.
- Your own packages are imported with the module path in front: `"example.com/school/marks"`.

### go.mod

**`go.mod`** = the module's main file. It lists the module's name, the Go version, and the modules it needs.

```text
module example.com/school

go 1.24

require github.com/google/uuid v1.6.0
```

- `module` = the module path.
- `go` = the Go version the module needs.
- `require` = another module this one depends on, and its version.

**Dependency** = a module your project needs in order to work.

### go.sum

**`go.sum`** = a list of security fingerprints (hashes) for every dependency.

```text
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TfrqmUiFvq4ySeL7d0WSkJs5V8BGcK3ZNg6tMHH9Jzw=
```

- Each line says: "this exact version has this exact content".
- If a download ever changes, Go notices and stops.
- Never edit it by hand. Go writes it for you.
- Keep both `go.mod` and `go.sum` in your project, and in Git.

### go mod tidy

**`go mod tidy`** = make `go.mod` and `go.sum` match your code.

- It **adds** modules that your code imports but `go.mod` is missing.
- It **removes** modules that your code no longer uses.
- Run it after you add or delete imports.

**Simple lesson:** `go mod init` starts a module, `go.mod` lists what it needs, `go.sum` checks it, and `go mod tidy` keeps them in step.

## Package Management

Click **Next step** to manage one dependency from start to finish.
Watch the files on the right.

### Installing Modules

```bash
go get github.com/google/uuid
```

- `go get` downloads the module and adds it to `go.mod`.
- Downloads are stored in your **GOPATH** folder, under `pkg/mod`.
- `go get github.com/google/uuid@v1.6.0` picks an exact version.

Then use it in your code:

```go
package main

import (
	"fmt"

	"github.com/google/uuid"
)

func main() {
	fmt.Println("Admission ID:", uuid.New())
}
```

- Standard library imports come first, then a blank line, then other modules.
- `go fmt` and most editors arrange this for you.

### Updating Modules

- `go get example.com/pkg@latest` = update one module to its newest version.
- `go get -u ./...` = update every dependency of your project.
- `go list -m all` = list every module your project uses.

### Removing Modules

- Delete the `import` from your code.
- Run `go mod tidy`. It removes the module from `go.mod` and `go.sum`.
- Or run `go get example.com/pkg@none` to remove it directly.

### Versions

**Semantic version** = a version number like `v1.6.0`: **major.minor.patch**.

- **Patch** (`v1.6.1`): bug fixes only.
- **Minor** (`v1.7.0`): new features, old code still works.
- **Major** (`v2.0.0`): changes that may break old code. Its import path ends in `/v2`.

`go get` and `go mod` need the internet and the `go` tool on your computer.

In this lab, programs can use only Go's standard library. Commands like these are shown in the terminal widget instead of being run.

**Simple lesson:** `go get` adds or updates a module, and `go mod tidy` removes what you no longer use.

## Popular Standard Packages

**Standard library** = the packages that come with Go. No `go get` needed.

| Package | Used for |
|---|---|
| `fmt` | printing and formatting text |
| `os` | files, folders, environment, program arguments |
| `strings` | working with text |
| `strconv` | converting between text and numbers |
| `math` | square roots, powers, rounding, π |
| `time` | dates, times and durations |
| `net/http` | web servers and web requests |
| `encoding/json` | reading and writing JSON |

### fmt, strings and strconv

```go runnable title="fmt, strings and strconv together"
package main

import (
	"fmt"
	"strconv"
	"strings"
)

func main() {
	name := strings.TrimSpace("  Kavya  ")
	roll := strconv.Itoa(17)
	fmt.Printf("%s has roll number %s\n", name, roll)
}
```

```text
Kavya has roll number 17
```

- `Printf` uses **verbs** like `%s` (text) and `%d` (number). `\n` ends the line.
- You will learn `strings` fully in **Strings**.

### math

```go runnable title="The math package"
package main

import (
	"fmt"
	"math"
)

func main() {
	fmt.Println(math.Sqrt(81), math.Pow(2, 10))
	fmt.Println(math.Round(7.5), math.Floor(7.9), math.Ceil(7.1))
	fmt.Printf("%.2f\n", math.Pi)
}
```

```text
9 1024
8 7 8
3.14
```

### os and time

```go runnable title="os and time"
package main

import (
	"fmt"
	"os"
	"time"
)

func main() {
	fmt.Println(os.Getenv("SCHOOL_CODE") == "")
	period := 45 * time.Minute
	fmt.Println("One period lasts", period)
}
```

```text
true
One period lasts 45m0s
```

- `os.Getenv` reads an **environment variable**: a setting outside the program. Here it is not set.
- You will learn `time` in **Time and Date**, and `os` files in **File Handling**.

### encoding/json

```go runnable title="encoding/json"
package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	data, _ := json.Marshal(map[string]int{"maths": 91, "science": 88})
	fmt.Println(string(data))
}
```

```text
{"maths":91,"science":88}
```

- You will learn JSON fully in **JSON**.

### net/http

`net/http` builds web servers in a few lines:

```go
package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "Welcome to Green Valley School")
	})
	http.ListenAndServe(":8080", nil)
}
```

- Run it on your computer, then open `http://localhost:8080` in a browser.
- This runs a real server, so it cannot run in this browser lab.

**Simple lesson:** Go's standard library already has packages for text, numbers, files, time, JSON and the web.

## TL;DR

1. **Package** = a folder of Go files with one name: `package marks`.
   - `package main` + `func main()` = a runnable program.
   - Names: short, lowercase, one word.
2. **Exported** = Capital first letter, usable outside. **Unexported** = small, stays inside.
3. **Import** = `import "strings"`, then `strings.ToUpper(...)`.
   - **Alias** = `import str "strings"`.
   - **Blank** = `import _ "image/png"`, for set-up only.
   - **Dot** = `import . "strconv"`, avoid it.
4. **Module** = a project with a `go.mod`.
   - `go mod init example.com/school`
   - **go.mod** = name, Go version, dependencies.
   - **go.sum** = hashes that check downloads.
   - `go mod tidy` = add missing, remove unused.
5. **Manage** = `go get pkg`, `go get pkg@latest`, `go get pkg@none`.
6. **Standard library** = `fmt`, `os`, `strings`, `strconv`, `math`, `time`, `net/http`, `encoding/json`.

## Common mistakes

| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
| Calling `marks.total()` from main | All names are shared | Only Capitalised names are exported | `undefined: marks.total` |
| Two package names in one folder | Each file picks its own package | One folder = one package | `found packages marks and report` |
| An import you do not use | Extra imports are harmless | Every import must be used, or be `_` | `imported and not used` |
| Editing `go.sum` by hand | It is a normal settings file | Go writes it, you keep it | Checksum errors when building. |
| Not committing `go.mod` and `go.sum` | Only `.go` files matter | Both belong in Git | Others cannot build your project. |
| Package named `Marks_Utils` | Any name works | Short, lowercase, no underscores | Hard to read and unusual. |
| Using `import .` everywhere | It saves typing | Readers cannot see where names come from | Confusing code. |

## Check Yourself

## Exercises

## What to Remember

- A package is a folder of Go files with one `package` name.
- `package main` with `func main()` is a program. Other packages are libraries.
- Capitalised names are exported. Lowercase names stay inside the package.
- Import normally, with an alias, blank (`_`) for set-up, or dot (avoid).
- A module is a project with `go.mod`. `go.sum` checks downloads.
- `go get` adds or updates. `go mod tidy` cleans up.
- The standard library covers text, numbers, files, time, JSON and the web.

Next: **Strings**. You will learn how to build, search, split and change text in Go.
