The go Command and Modules

Real Go projects are organised as modules: a folder of code with a go.mod file that names the project and records the Go version and any libraries it depends on. This lesson creates a module, splits a program across files, and tours the go subcommands you'll use every day — run, build, fmt, vet, get, mod tidy and install.

Creating a module

Make a folder for the project and run go mod init with a module path. The path is the module's name; if you plan to publish the code it's usually the repository address, such as github.com/yourname/hello:

$
mkdir hello && cd hello
go mod init example.com/hello
Output
go: creating new go.mod: module example.com/hello

The new go.mod file is short:

GO.MOD
module example.com/hello

go 1.27.1

The go line records the language version the module is written for. It turns on that version's features, and if someone with an older toolchain builds the module, the go command fetches a new enough one for them.

A program in several files

A package can be split across any number of .go files in the same folder. They all share one namespace, so a function declared in one file can be called from another without importing anything:

GO.MOD
module example.com/hello

go 1.27
GO greet.go
package main

import "strings"

func greeting(name string) string {
	return "Hello, " + strings.ToUpper(name[:1]) + name[1:] + "!"
}
GO main.go
package main

import "fmt"

func main() {
	fmt.Println(greeting("gopher"))
	fmt.Println(greeting("world"))
}

Run the whole package with a dot, meaning "the package in this folder":

$
go run .
Output
Hello, Gopher!
Hello, World!

Running go run main.go here would fail, because it compiles only that one file and greeting lives in the other. Inside a module, get into the habit of using go run ..

Building and installing

$
go build            # creates ./hello (hello.exe on Windows), named after the module
go build -o app     # choose the output name
go install          # builds and copies the program into ~/go/bin

After go install, you can run hello from any folder, provided ~/go/bin is on your PATH. The same command installs tools other people have published: go install example.com/some/tool@latest.

Formatting and checking code

go fmt (which runs gofmt) rewrites your files into the standard layout. Given this badly spaced file:

GO messy.go
package main
import "fmt"
func main(){
fmt.Println( "tidy me" )
}

running go fmt prints the names of the files it changed and leaves this behind:

GO messy.go
package main

import "fmt"

func main() {
	fmt.Println("tidy me")
}

go vet goes further and looks for code that compiles but is probably wrong, such as a Printf whose placeholders don't match its arguments. Run both before every commit; editors usually run them on save.

Using a third-party package

Packages from outside the standard library are imported by their module path. This program uses golang.org/x/text, a set of text-processing packages maintained by the Go team:

GO main.go
package main

import (
	"fmt"

	"golang.org/x/text/cases"
	"golang.org/x/text/language"
)

func main() {
	title := cases.Title(language.English)
	fmt.Println(title.String("the go programming language"))
}

The first go run . fails and tells you what to do:

Output
main.go:6:2: no required module provides package golang.org/x/text/cases; to add it:
	go get golang.org/x/text/cases
main.go:7:2: no required module provides package golang.org/x/text/language; to add it:
	go get golang.org/x/text/language

go get downloads the module and records it in go.mod; then the program runs:

$
go get golang.org/x/text
go run .
Output
go: downloading golang.org/x/text v0.42.0
go: added golang.org/x/text v0.42.0
The Go Programming Language

The go.mod file now has a require line, and a second file, go.sum, holds cryptographic checksums of everything downloaded so that later builds get exactly the same code. Commit both files. Running go mod tidy keeps go.mod accurate: it adds requirements your code imports, removes ones it no longer uses, and drops the // indirect marker go get left here, since the code now imports the package directly:

GO.MOD
module example.com/words

go 1.27.1

require golang.org/x/text v0.42.0

Modules are downloaded once into a shared cache (inside ~/go/pkg/mod) and reused by every project. You can search for packages and read their documentation on pkg.go.dev.

Command reference

CommandWhat it does
go mod init pathStarts a new module in the current folder
go run .Compiles and runs the package in this folder
go buildCompiles an executable into the current folder
go installCompiles and installs into ~/go/bin
go fmt ./...Formats every package in the module (./... means "this folder and everything below it")
go vet ./...Reports suspicious code
go test ./...Runs tests (lesson 65)
go get module@versionAdds or upgrades a dependency; @none removes it
go mod tidyMakes go.mod and go.sum match the imports
go doc strings.SplitShows documentation
go fix ./...Updates code to newer idioms and APIs automatically (lesson 68)
Tip: every example in the rest of this course is a single main.go file unless it says otherwise. The easiest way to run them is one scratch module: go mod init example.com/scratch once, then replace main.go and use go run . each time.
Next: the building blocks of Go syntax.