Setting Up Go
Install Go, understand modules and GOPATH, configure VS Code with gopls, and write your first working program.
Installing Go
Go provides official installers for all major platforms. The installation is intentionally straightforward — one package to download, and the toolchain is ready. Always install from the official site to get the latest stable release with security patches.
Linux / macOS
Download the latest release from go.dev/dl, extract it, and add it to your PATH:
# Example for Go 1.22 on Linux amd64
wget https://go.dev/dl/go1.22.0.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz
# Add to ~/.bashrc or ~/.zshrc
export PATH=$PATH:/usr/local/go/bin
Windows
Download the .msi installer from go.dev/dl and run it. It sets PATH automatically.
Verify installation
After installation, confirm the toolchain is on your PATH and shows the expected version:
go version
# go version go1.22.0 linux/amd64
Understanding GOPATH and Go Modules
Understanding the shift from GOPATH to modules will save you confusion when reading older Go tutorials or working on legacy codebases. The two systems work very differently.
The old way — GOPATH
Before Go 1.11, all Go code had to live inside $GOPATH/src. This was rigid and made multi-project work awkward — every project had to be nested inside a single global workspace directory.
The modern way — Go Modules
Modules let you place projects anywhere on your filesystem. Each project has a go.mod file that defines the module name and tracks dependencies, similar to package.json in Node or Cargo.toml in Rust. This is the only approach you need to learn for new projects.
$HOME/
projects/
myapp/ ← project can live anywhere
go.mod
go.sum
main.go
internal/
GOPATH still exists at ~/go by default. Go uses it as:
~/go/bin— installed binaries (go installputs executables here)~/go/pkg/mod— downloaded module cache
Creating Your First Module
Every Go project starts with go mod init. This creates the go.mod file that anchors the project and establishes the import path prefix for all packages within it. Run this once when you start a new project.
mkdir myapp && cd myapp
go mod init github.com/yourname/myapp
This creates go.mod:
module github.com/yourname/myapp
go 1.22
The module path (github.com/yourname/myapp) is used as the base for all import paths within the project. It doesn’t have to match a real GitHub URL for local development, but it should if you plan to publish.
Project Layout
Go has no enforced directory structure, but the community has converged on a set of conventions that make projects easy to navigate. Following these conventions means other Go developers will immediately understand your project layout.
myapp/
├── go.mod
├── go.sum # checksums for dependencies
├── main.go # entry point
├── internal/ # private packages (not importable by other modules)
│ └── db/
│ └── db.go
├── pkg/ # public packages (importable by other modules)
│ └── config/
│ └── config.go
└── cmd/ # multiple binaries
├── server/
│ └── main.go
└── worker/
└── main.go
Adding Dependencies
Go’s dependency management is built into the go command — no separate package manager needed. go get fetches and pins a specific version; go mod tidy keeps the go.mod and go.sum files in sync with what your code actually imports.
# Add a dependency
go get github.com/gin-gonic/gin@v1.9.1
# Remove unused dependencies and tidy go.sum
go mod tidy
# Vendor dependencies (optional, for reproducible builds)
go mod vendor
Setting Up VS Code
VS Code with the official Go extension gives you autocompletion, inline type information, automatic imports, integrated debugging, and test running — all powered by gopls, the Go language server. This setup is free and covers everything you need for professional Go development.
- Install VS Code
- Install the Go extension (publisher:
golang.go) - Open a
.gofile — VS Code prompts to install tools. Click Install All
This installs gopls (the Go language server), dlv (debugger), staticcheck, and other tools.
Useful VS Code settings for Go (settings.json):
{
"go.useLanguageServer": true,
"editor.formatOnSave": true,
"[go]": {
"editor.defaultFormatter": "golang.go"
},
"go.lintTool": "staticcheck",
"go.testFlags": ["-v", "-race"]
}
Your First Complete Program
This program demonstrates the core mechanics of a real Go program: reading command-line arguments, using the standard library, and handling optional input gracefully. It’s small but shows how Go code is structured in practice.
// main.go
package main
import (
"fmt"
"os"
)
func main() {
// Command-line args are in os.Args
// os.Args[0] is the program name
name := "World"
if len(os.Args) > 1 {
name = os.Args[1]
}
fmt.Printf("Hello, %s!\n", name)
}
go run main.go
# Hello, World!
go run main.go Gopher
# Hello, Gopher!
# Build a binary
go build -o hello .
./hello Alice
# Hello, Alice!
Essential Go Commands
These are the commands you’ll use every day. The go tool is the single entry point for building, testing, formatting, and managing dependencies — there is no separate build tool or task runner to learn.
| Command | What it does |
|---|---|
go run . | Compile and run without saving a binary |
go build . | Compile to a binary in the current directory |
go test ./... | Run all tests in all packages |
go fmt ./... | Format all Go source files |
go vet ./... | Run the Go static analyzer |
go mod tidy | Add missing, remove unused module requirements |
go get pkg@version | Add or update a dependency |
go install tool@latest | Install a Go tool to $GOPATH/bin |
go doc fmt.Println | Show documentation for a symbol |
Cross-Compilation
One of Go’s standout features is that the compiler can produce binaries for any supported platform from any platform — no cross-compilation toolchain, no Docker containers, no special setup required. This makes it trivial to ship Linux server binaries from a macOS laptop, or to produce Windows executables from a CI server running Linux.
# Build a Linux binary from macOS or Windows
GOOS=linux GOARCH=amd64 go build -o app-linux .
# Build for Windows from Linux
GOOS=windows GOARCH=amd64 go build -o app.exe .
# Build for Apple Silicon (ARM)
GOOS=darwin GOARCH=arm64 go build -o app-mac-arm .
No cross-compilation toolchain needed — the Go compiler handles everything.
The Go Playground
For quick experiments without a local setup, use play.golang.org. It runs Go code in the browser and lets you share snippets via URL. This is particularly useful for reproducing bugs or sharing example code with colleagues.
Next: Variables in Go — learn how Go handles variable declarations and type inference.