Skip to main content
Go Language Fundamentals for Beginners to Advanced
CHAPTER 17 Beginner

Packages and Modules

Updated: May 17, 2026
5 min read

# CHAPTER 17

Packages and Modules

1. Introduction

Until now, all our code has been in a single file inside package main. In real-world projects, you will have dozens of files for database connections, routing, and business logic. Go organizes code into Packages (folders of related code) and manages external dependencies using Modules.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Understand what a Package is in Go.
  • Export and Unexport variables and functions using Capitalization.
  • Create and import your own custom packages.
  • Understand Go Modules (go.mod).
  • Download third-party packages using go get.

3. What is a Package?

A Package is simply a directory (folder) containing one or more .go files. Every file inside that folder must declare the same package name at the very top (e.g., package mathutils).

4. Visibility Rules (Exported vs Unexported)

In Java or C#, you use keywords like public, private, or protected to control what other files can see. Go does not have these keywords. Instead, Go uses a brilliant, simple rule based on Capitalization.
  • Exported (Public): If a variable, struct, or function starts with a Capital Letter, it can be accessed by *other* packages. (e.g., func CalculateTax(), type User struct).
  • Unexported (Private): If it starts with a lowercase letter, it is strictly private to its own package. Other packages cannot see or use it. (e.g., func calculateTax(), var dbPassword string).

*(This is why we use fmt.Println and not fmt.println! Println is Exported by the fmt package).*

5. Creating Custom Packages

Let's organize a project.

Project Structure:

text
12345
my-app/
├── go.mod
├── main.go
└── mathutils/
    └── calc.go

1. Create calc.go inside the mathutils folder:

go
1234567891011
package mathutils

// Exported function (Capital 'A')
func Add(a, b int) int {
    return a + b
}

// Unexported function (Lowercase 's') - Cannot be used outside this package
func subtract(a, b int) int {
    return a - b
}

2. Import and use it in main.go:

go
12345678910111213
package main

import (
    "fmt"
    "my-app/mathutils" // Import based on the module name + folder path
)

func main() {
    result := mathutils.Add(10, 5) // Works!
    fmt.Println(result)

    // mathutils.subtract(10, 5) // ERROR! subtract is unexported (private)
}

6. Go Modules (go.mod)

A Go Module is a collection of packages that are versioned together. It is initialized by running go mod init <module-name> in the root folder of your project.

The generated go.mod file tracks:

  1. 1. The module's exact name.
  1. 2. The Go version required.
  1. 3. Any third-party dependencies you install.

7. Downloading External Dependencies (go get)

To use code written by other developers (like a database driver or a web framework), you use the go get command.
bash
12
// Example: Downloading the popular Gorilla Mux router
go get github.com/gorilla/mux

When you run this:

  1. 1. Go downloads the code from GitHub.
  1. 2. It adds the version to your go.mod file.
  1. 3. It generates a go.sum file (which locks the exact version cryptographically for security).

You can then use it in your code:

go
1
import "github.com/gorilla/mux"

8. Common Mistakes

  • Circular Dependencies: If Package A imports Package B, and Package B imports Package A, the Go compiler will throw a fatal error. You must refactor your code to flow in one direction.
  • Lowercasing Struct Fields: If you create an exported struct (type User struct) but its fields are lowercase (name string), other packages can instantiate the User but cannot access the name field! Always capitalize fields you want to be public (Name string).

9. Best Practices

  • Package Naming: Package names should be short, single-word, lowercase names. Avoid snakecase or camelCase (use mathutils, not MathUtils or mathutils).
  • Organize by Domain: Group files by what they *do* (e.g., package auth, package payment), not by their architectural role (e.g., avoid package models, package controllers).

10. Exercises

  1. 1. Create a module using go mod init my-project.
  1. 2. Create a subfolder stringutils and write an exported function Reverse(s string) string.
  1. 3. Call it from main.go.

11. MCQs with Answers & Explanations

Question 1

What is a Package in Go?

Question 2

How does Go determine if a function is Public (Exported) or Private (Unexported)?

Q3. If a struct field is named password, can code outside its package access it? a) Yes b) No Answer: b) No. *Explanation: It starts with a lowercase letter, making it Unexported (Private).*
Question 4

What is the purpose of the go.mod file?

Question 5

Which terminal command is used to download third-party packages?

Question 6

What happens if Package A imports Package B, and Package B imports Package A?

Q7. Is fmt.println() a valid function call? a) Yes b) No Answer: b) No. *Explanation: It must be fmt.Println() because the 'P' must be capitalized to be exported from the fmt package.*
Question 8

What file does Go automatically generate to cryptographically lock the exact versions of downloaded packages?

Question 9

Which is a good Go package name?

Q10. Can multiple .go files exist inside the same package folder? a) Yes, as long as they all declare the same package name at the top b) No, one file per folder Answer: a) Yes.

12. Interview Preparation

Interview Questions:
  1. 1. How does Go handle Encapsulation (Access Modifiers) without using public or private keywords?
  1. 2. Explain the role of go.mod and go.sum in a Go project.
  1. 3. What is a Circular Dependency, and why does Go strictly forbid it?

13. Summary

Organizing code effectively is critical for enterprise software. Go Modules (go.mod) modernizes dependency management, while Packages allow you to group related logic. By simply capitalizing the first letter of a name, you instantly control the visibility (Exported vs Unexported) of your code, keeping the language clean and free of boilerplate access modifiers.

14. Next Chapter Recommendation

Backend servers frequently need to read configuration files, logs, and user uploads. In Chapter 18: File Handling in Go, we will learn how to interact with the Operating System to read, write, and manage files on the hard drive.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·