Let’s write your first Go program. We’ll do it the proper way — as a real Go module — so you understand the foundation every Go project sits on.

Create a module

A module is just a fancy word for “a Go project”. Every Go project is a module, and every module has a name.

In your terminal, navigate to the folder you created in the previous lesson and initialize a module:

cd ~/code/golang-fundamentals
go mod init hello

You’ll see Go create a single file:

go: creating new go.mod: module hello

Open the folder in your editor. You’ll see a file named go.mod containing:

module hello

go 1.26

That’s it. go.mod is the heartbeat of every Go module — it records the module’s name and the Go version it targets. We’ll do more with it later. For now, leave it alone.

Write the program

Create a new file in the same folder named main.go and type (don’t paste — typing helps it stick):

package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

Save the file.

Run it

Back in your terminal, run:

go run main.go

You should see:

Hello, World!

Congratulations. You’ve just written, compiled, and run your first Go program.

If you got an error, the most common causes are:

  • Typo in the code — Go is strict; even a missing brace or quote will stop it
  • Wrong folder — make sure your terminal is cd’d into the folder containing main.go
  • No module — if you skipped go mod init, Go will complain

Understanding what just happened

Let’s walk through that program line by line.

package main

Every Go file starts with a package declaration. A package is a group of related files. The special name main tells Go: “this is a program I want to run.” Other package names produce libraries — code meant to be imported and used by other programs.

import "fmt"

fmt (short for “format”) is a package from Go’s standard library — a huge collection of code that ships with Go itself. We import it so we can use its Println function. Without this line, the next line would fail.

func main() {

func is how you declare a function — a named block of code that does something. main is special: when you run a program, Go looks for a function called main and runs it. Every runnable Go program has exactly one main function.

The () is where you’d list inputs the function takes. main takes no inputs, so the parentheses are empty.

The { opens a block — everything between { and } is the body of the function.

    fmt.Println("Hello, World!")

fmt.Println calls the Println function from the fmt package. The . is how you reach into a package to use what’s inside it. We pass it one argument — the string "Hello, World!" — and it prints that string followed by a newline.

}

The closing brace ends the function.

go run vs go build

You used go run main.go, which compiles and runs your program in one step. It’s perfect while you’re learning.

If you want a permanent executable — a binary file you can run without Go installed — use go build:

go build

This produces a file named hello (matching your module name) on macOS/Linux, or hello.exe on Windows. Run it directly:

./hello
Hello, World!

That single binary is everything your program needs. No runtime, no interpreter, no dependencies. You can copy it to another machine of the same OS and architecture, and it just runs. This is one of Go’s superpowers.

A few more useful commands

While we’re here, three more commands you’ll use constantly:

go fmt             # automatically format your code in the standard Go style
go vet             # check for common mistakes
go mod tidy        # clean up unused imports and dependencies

go fmt is worth special mention: Go has one official code style, and go fmt enforces it. There are no debates about tabs vs spaces or where braces go. Just run go fmt and move on. (Most editors run it automatically every time you save.)

What’s next

You have a working Go installation, a real Go module, and a running program. Section 1 is done.

In the next section, we’ll learn the building blocks of any program: variables, types, and how Go handles data.

Toggle theme (T)