Lesson 1.1

Packages, Modules, and the main Function

When you first start learning Go, the syntax might look simple — but beneath the surface are a few extremely important rules that every Go program must follow.

What you'll learn
  • How Go organizes code using packages
  • Why the main package is special and how it works
  • What the main function is and why it's essential
  • How import statements and the standard library work
  • What Go modules are and how they're used
  • How to build an executable using go build

The Three Key Parts of Every Go Program

Let's look at a simple Go file:

go
package main

import "fmt"

func main() {
    fmt.Print("Hello world")
}

This program already contains the fundamental components of any valid Go program:

Package declaration

Defines which package the file belongs to

Import statements

Brings in external functionality (optional)

main function

Entry point of the program

1. Packages — How Go Organizes Code

At the top of every Go file, you must declare a package:

go
package main

If you remove this line, Go will throw an error:

Expected package clause but found 'import'...

What is a package?

A package is simply a way to group related Go files together.

  • Every Go file belongs to exactly one package
  • A package may span multiple files
  • Examples: fmt, http, users, main

Why main?

Because main is a special package.

When a Go program is compiled into an executable, Go needs to know: "Where does the program start?"

If your package is named main, Go treats it as the entry point. If it isn't named main, Go will not produce an executable.

go
// If you rename it to:
package app

// And run:
go build

// → No executable output, because Go found no entry point

2. The import Statement — Bringing in External Functionality

The line:

go
import "fmt"

brings in Go's built-in fmt (format) package.

Go's standard library is huge, and fmt provides printing functions such as Print, Println, and Printf.

When you write:

go
fmt.Print("Hello")

you are calling a function from the fmt package. The value "Hello" is a string literal, always enclosed in double quotes (single quotes are not allowed for strings in Go).

Go Standard Library

Go includes an extensive standard library with packages for everything from HTTP servers to file handling, JSON, cryptography, and much more — all built in.

3. The main Function — The Program's Entry Point

Inside the main package, Go expects exactly one function named main:

go
func main() {
    fmt.Print("Hello world")
}

This is the first code executed when the program starts.

Important Rules for the main function:
  • 1.There must be one and only one main function per package
  • 2.It cannot take arguments and cannot return a value
  • 3.Go does not execute code that sits at the top level (outside functions), unlike languages such as JavaScript

Key Insight

The main function is effectively your program's starting point. Without it, Go doesn't know where to start executing.

4. Enter Go Modules — Your Project's Identity

When you run:

go
go build

in a totally fresh folder, you may get this:

go: cannot find main module...

That's because Go requires your project to be part of a module.

A module is simply a Go project with an identity.

You create one with:

go
go mod init go-youtube

This generates a go.mod file:

go
module go-youtube

go 1.23.5

From now on, Go recognizes the folder as a module, and go build will work.

Best Practice for Naming Go Modules

Recommended: Use a fully qualified import path

The Go ecosystem expects module names to look like this:

go
go mod init github.com/username/repo
go mod init gitlab.com/username/repo
go mod init example.com/project-name

This is because your module name doubles as its import path if others (or future you) want to use it as a dependency.

⚠️ Not Idiomatic: Short local names

Avoid names like:

go
go mod init go-youtube
go mod init myapp
go mod init test

Why it's not ideal:

  • If you import your own module later, paths look weird: import "go-youtube/utils"
  • If you move the repo to GitHub later, you break all imports
  • It doesn't tell Go (or other devs) where the module lives

Best practice example

go
go mod init github.com/go-backend-journey/go-youtube

Even if you never publish it to GitHub, it's still perfectly valid. Go modules don't require the repo to exist — it's just a namespace.

5. Building a Standalone Executable

Once your module exists, you can build your program:

go
go build

This produces an executable:

  • On Windows → go-youtube.exe
  • On Mac/Linux → go-youtube

Double-click or run:

go
./go-youtube

The output appears — even on machines without Go installed.

Go's Power

This is one of Go's strongest features: you build real, native executables. No runtime, no dependencies — just a single binary that can run anywhere.

Summary

Key Takeaways
  • Packages: Every Go file belongs to a package. The main package is special — it creates an executable program.
  • Imports: Bring functionality from other packages. Go's standard library includes everything from fmt to http.
  • main function: Your program's entry point. Must be in the main package, cannot take parameters or return values.
  • Modules: Define your project's identity. Create them using go mod init with a fully qualified path.
  • Build: go build creates native executables that work without a Go runtime.

Practical Exercise

Challenge: Create Your First Go Program

Practice everything you've learned:

  1. Create a new folder for your project
  2. Initialize a Go module with a proper name (e.g., github.com/your-name/hello-go)
  3. Create a main.go file with package main and main function
  4. Import the fmt package
  5. Print a message that includes your name and why you're learning Go
  6. Build the program using go build
  7. Run the generated executable

Bonus challenge:

Try changing package main to package app and run go build. What happens? Why?