The terminal doesn't know Go yet
You open your terminal on a fresh Mac, type go run main.go, and get a cold zsh: command not found: go. You already downloaded the installer. You clicked through the prompts. The terminal just doesn't know where to look. Setting up Go on macOS is less about downloading a file and more about teaching your shell how to find the toolchain, where to cache dependencies, and how to keep your workspace clean.
What actually happens when you install Go
Installing Go isn't like installing a single app from the App Store. It drops a complete compiler, a linker, a formatter, and a package manager into your system. Think of it like setting up a workshop. You need the tools on the bench, a storage cabinet for parts you download, and a clear rulebook for where your projects live. macOS handles the bench automatically if you pick the right installer, but the cabinet and rulebook need a quick introduction.
The go binary is just the door. Behind it sits the toolchain, which manages compilation, dependency resolution, and formatting. When you run any go command, the toolchain reads environment variables to find your module cache, your workspace root, and your network proxy settings. Modern Go relies on modules, which means every project declares its own dependencies and version constraints. The old GOPATH directory still exists for backward compatibility, but it no longer dictates where your code lives.
The binary is just the door. The module cache is the house.
Get the binary on your system
Here is the fastest way to get the toolchain onto your Mac.
# Homebrew downloads the precompiled binary and links it to your PATH
brew install go
# Verify the compiler is reachable and reports its version
go version
If you prefer the official installer, grab the .pkg file from the Go download page and run it. The installer places the toolchain in /usr/local/go and updates your shell profile automatically. Both methods give you the same compiler. Homebrew simply wraps the download in a package manager that handles updates alongside your other CLI tools.
If the terminal still says zsh: command not found: go, your shell hasn't loaded the updated PATH. Run source ~/.zshrc or restart the terminal window. The go command should immediately return a version string like go version go1.22.4 darwin/arm64.
How the toolchain maps your workspace
Once the binary works, the next step is understanding where Go stores things. Run go env in your terminal. You will see a long list of variables. Two matter most for daily development.
GOMODCACHE points to ~/go/pkg/mod. This is where Go downloads every dependency your projects request. The cache is shared across all projects, so installing a library once means every new project can reuse it instantly. GOPATH points to ~/go. Historically, this was where you stored your own code. Modern Go ignores it for new projects. It only matters if you are maintaining legacy code that predates modules.
Here is how you inspect your current environment without guessing.
# Print the active module cache directory
go env GOMODCACHE
# Print the workspace root (mostly legacy now)
go env GOPATH
# Show the network proxy Go uses to fetch modules
go env GOPROXY
The convention in the Go community is to let go env dictate your setup. You rarely need to override these variables manually. If you do change them, export them in your shell profile so every new terminal session inherits the same paths. The toolchain expects consistency.
Modules define your boundaries. Keep them clean.
Set up a real project directory
Here is how you initialize a project the way the community expects it.
# Create a dedicated directory outside of your home folder
mkdir -p ~/projects/hello-go
cd ~/projects/hello-go
# Initialize a module with a unique identifier for your project
go mod init example.com/hello-go
# Create the entry point file
cat > main.go <<EOF
package main
import "fmt"
func main() {
// Print a confirmation message to standard output
fmt.Println("Go is ready on macOS")
}
EOF
# Compile and run the program in one step
go run main.go
The go mod init command creates a go.mod file. This file records your module path and tracks dependency versions. The module path should be a URL that you control. Use example.com for throwaway projects. Use your actual domain or GitHub username for real work. Never use localhost or a bare directory name. The Go toolchain uses the module path to generate import statements and to verify that dependencies match their published versions.
When you run go run main.go, the toolchain compiles the code into a temporary directory, executes the binary, and deletes the temporary files. It is fast for testing. For production or debugging, use go build instead. go build writes a permanent binary to your current directory that you can run, move, or inspect with strings and otool.
A missing PATH variable breaks everything. Verify it before you write a single line of code.
Common setup failures and how to fix them
New setups usually fail in three predictable ways.
The first failure is a missing binary. The terminal returns zsh: command not found: go. This means your shell's PATH does not include /usr/local/go/bin or the Homebrew prefix. Fix it by reloading your shell configuration or by adding the directory to your ~/.zshrc file. The official installer does this automatically. Homebrew does it automatically. Manual installations require you to add export PATH=$PATH:/usr/local/go/bin to your profile.
The second failure is a module mismatch. The compiler rejects the program with go: cannot find main module, but found .git in /path/to/dir. This happens when you run go run or go build inside a directory that lacks a go.mod file. Go requires every project to declare a module. Run go mod init your-module-path in the project root. The error disappears.
The third failure is a package structure mistake. The compiler complains with package command-line-arguments is not a main package. This means you tried to run a file that declares package utils instead of package main. Only package main files can produce executable binaries. Library packages compile into .a archives and get linked by other programs. Fix it by changing the package declaration or by running the correct entry point file.
Network issues also surface during setup. If go mod tidy hangs, check your GOPROXY setting. Go uses a public proxy by default to speed up downloads and provide caching. Corporate firewalls sometimes block it. Set GOPROXY=https://proxy.golang.org,direct in your environment if you need to bypass strict network policies.
The worst setup bug is the one that silently uses the wrong Go version. Run go version before every major project switch. Version mismatches cause subtle compilation differences and dependency resolution failures.
Pick your installation path
Use Homebrew when you want automatic updates and seamless integration with other command-line tools. Use the official .pkg installer when you prefer a static, system-level installation that doesn't rely on third-party package managers. Use a version manager like goenv when you need to switch between multiple Go versions for different projects. Use the official Docker image when you want a completely isolated environment that leaves your host system untouched.
Pick one path. Stick with it until you have a reason to change.