Setup

Get a Go project running from scratch.

Install Go

# macOS
brew install go

# Linux
wget https://go.dev/dl/go1.24.1.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.24.1.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin

# Verify
go version

Add to your shell profile:

export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin

Create a Project

mkdir myapp && cd myapp
go mod init github.com/yourname/myapp

This creates go.mod, which tracks your module name and dependencies:

module github.com/yourname/myapp

go 1.24

Write a main.go:

package main

import "fmt"

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

Run it:

go run main.go        # compile and run
go build -o myapp     # compile to binary
./myapp               # run the binary

Project Structure

Small projects:

myapp/
  go.mod
  go.sum
  main.go

Growing projects:

myapp/
  go.mod
  go.sum
  main.go              # or cmd/myapp/main.go
  internal/            # private packages (not importable outside module)
    server/
      server.go
      server_test.go
    store/
      store.go
  pkg/                 # public packages (optional, many projects skip this)

Larger projects with multiple binaries:

myapp/
  go.mod
  cmd/
    server/main.go     # go run ./cmd/server
    cli/main.go        # go run ./cmd/cli
  internal/
    ...

Tip: Start with everything in main.go. Extract packages when you have a reason to, not before.

Add Dependencies

# Add a package (updates go.mod and go.sum)
go get github.com/go-chi/chi/v5

# Use it in your code
import "github.com/go-chi/chi/v5"

# Tidy up (remove unused deps, add missing ones)
go mod tidy

# Update all dependencies
go get -u ./...

# Update a specific dependency
go get -u github.com/go-chi/chi/v5

go.sum contains checksums for dependency verification. Commit both go.mod and go.sum.

Build and Run

# Run without building
go run .                # runs package in current dir
go run ./cmd/server     # runs a specific command

# Build
go build -o myapp .     # build current package
go build ./...          # build everything (check for errors)

# Install (builds and puts binary in $GOPATH/bin)
go install ./cmd/server

# Cross-compile
GOOS=linux GOARCH=amd64 go build -o myapp-linux .
GOOS=windows GOARCH=amd64 go build -o myapp.exe .
GOOS=darwin GOARCH=arm64 go build -o myapp-mac .

Common Commands

go test ./...           # run all tests
go test -v ./...        # verbose test output
go test -cover ./...    # with coverage
go vet ./...            # static analysis
go fmt ./...            # format all files
go doc fmt.Println      # view documentation

IDE Setup

VS Code: Install the Go extension. It uses gopls (the Go language server) for autocomplete, go-to-definition, and diagnostics.

GoLand: Works out of the box. Commercial IDE from JetBrains.

Neovim: Use nvim-lspconfig with gopls.

Essential gopls features that work across all editors:

  • Auto-import on save
  • Inline error diagnostics
  • Rename across files
  • Go to definition / find references
  • Auto-complete with type info

Tip: Run go install golang.org/x/tools/gopls@latest to get the latest language server.

Useful Tools

# Linter (catches bugs the compiler misses)
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
golangci-lint run

# Hot reload for development
go install github.com/air-verse/air@latest
air  # watches files, rebuilds and restarts on change

# Vulnerability checking
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...

Next: API Server | Concurrency