1 Go Command Toolchain
Go ships with an all-in-one toolchain. Unlike most languages, you rarely need external build tools β go handles compilation, testing, formatting, and dependency management.
| Command | Purpose | Example |
|---|---|---|
go build |
Compile packages and produce binary | go build -o myapp . |
go run |
Compile and run in one step | go run main.go |
go test |
Run tests and benchmarks | go test ./... |
go fmt |
Format source code (canonical style) | go fmt ./... |
go vet |
Static analysis for common bugs | go vet ./... |
go mod tidy |
Clean up go.mod and go.sum | go mod tidy |
go install |
Install a binary to $GOPATH/bin | go install golang.org/x/tools/...@latest |
# Initialize a new module
go mod init github.com/user/myproject
# Add a dependency (automatically updates go.mod)
go get github.com/gin-gonic/gin@latest
# Build for current platform
go build -o myapp .
# Run directly without creating a binary
go run .
# Format all files in project
go fmt ./...
# Run static analysis
go vet ./...
# Clean module cache
go clean -modcache
# List all dependencies
go list -m all
π‘ The ./... Pattern
./... is a wildcard that matches the current directory and all subdirectories. It's used with almost every go command to operate on the entire project.
2 Testing
Go has a built-in testing package and go test command. Test files end with _test.go and test functions start with Test. No external framework needed.
Basic Test
math.go
package math
func Add(a, b int) int {
return a + b
}
func Divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
math_test.go
package math
import "testing"
func TestAdd(t *testing.T) {
got := Add(2, 3)
want := 5
if got != want {
t.Errorf("Add(2, 3) = %d, want %d", got, want)
}
}
func TestDivide(t *testing.T) {
_, err := Divide(10, 0)
if err == nil {
t.Error("expected error for division by zero")
}
}
Table-Driven Tests
func TestAdd(t *testing.T) {
tests := []struct {
name string
a, b int
expected int
}{
{"positive numbers", 2, 3, 5},
{"negative numbers", -1, -2, -3},
{"zero", 0, 0, 0},
{"mixed", -1, 5, 4},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := Add(tt.a, tt.b)
if got != tt.expected {
t.Errorf("Add(%d, %d) = %d, want %d", tt.a, tt.b, got, tt.expected)
}
})
}
}
Benchmarks
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
Add(100, 200)
}
}
// Run benchmarks:
// go test -bench=. -benchmem
Running Tests
# Run all tests
go test ./...
# Run with verbose output
go test -v ./...
# Run specific test by name
go test -run TestAdd ./...
# Run with coverage report
go test -cover ./...
# Generate HTML coverage report
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
# Run benchmarks
go test -bench=. -benchmem ./...
π Comparison: Testing Frameworks
Go (go test)
Built-in, no dependencies. Table-driven tests. Built-in benchmarking and coverage.
PHP (PHPUnit)
Third-party via Composer. Class-based with assertions. Data providers for parameterized tests.
JS (Jest)
Third-party via npm. describe/it blocks. Mocking and snapshot testing built-in.
Python (pytest)
Third-party via pip. Function-based with fixtures. parametrize decorator for test tables.
3 Code Quality
Go enforces code quality through built-in tools. gofmt eliminates style debates, while go vet and golangci-lint catch bugs and anti-patterns.
go vet β Built-in Static Analysis
# Catches common mistakes like:
# - Printf format string mismatches
# - Unreachable code
# - Incorrect struct tags
# - Copying locks by value
go vet ./...
gofmt & goimports
# gofmt β canonical code formatting (built-in)
gofmt -w .
# goimports β gofmt + auto-manage import statements
go install golang.org/x/tools/cmd/goimports@latest
goimports -w .
Go's Formatting Philosophy
Go has one canonical code style enforced by gofmt. There are no config files, no arguments about tabs vs spaces. All Go code looks the same β this is by design and considered a major productivity win.
golangci-lint β Comprehensive Linter
# Install
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
# Run all default linters
golangci-lint run
# Run specific linters
golangci-lint run --enable errcheck,govet,staticcheck
# Fix auto-fixable issues
golangci-lint run --fix
golangci-lint bundles 50+ linters. Key ones include:
errcheck
Finds unchecked errors
staticcheck
Advanced static analysis
gosimple
Suggests code simplifications
gocritic
Opinionated style checks
ineffassign
Detects ineffectual assignments
unused
Finds unused code
4 Popular Third-Party Libraries
While Go's standard library is powerful, these third-party libraries have become de facto standards in the ecosystem.
π Web Frameworks
Gin
The most popular Go web framework. Fast routing with radix tree, middleware support, JSON validation.
r := gin.Default()
r.GET("/users/:id", getUser)
r.POST("/users", createUser)
r.Run(":8080")
Echo
High-performance, minimalist framework. Built-in middleware, data binding, and automatic TLS.
e := echo.New()
e.GET("/users/:id", getUser)
e.POST("/users", createUser)
e.Start(":8080")
Fiber
Express-inspired framework built on fasthttp. Familiar API for Node.js developers.
app := fiber.New()
app.Get("/users/:id", getUser)
app.Post("/users", createUser)
app.Listen(":8080")
ποΈ ORM & Database
GORM
Full-featured ORM. Auto migrations, associations, hooks, preloading. Supports MySQL, PostgreSQL, SQLite, SQL Server.
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
db.AutoMigrate(&User{})
db.Create(&User{Name: "Alice"})
var user User
db.First(&user, 1)
db.Where("age > ?", 18).Find(&users)
sqlx
Extends database/sql with named parameters and struct scanning. Lighter alternative to GORM.
db := sqlx.MustConnect("mysql", dsn)
var users []User
db.Select(&users, "SELECT * FROM users WHERE age > ?", 18)
db.NamedExec("INSERT INTO users (name, email) VALUES (:name, :email)", user)
π§ Utilities
zap
Logging
Uber's blazing-fast structured logger. Zero-allocation in hot paths.
zerolog
Logging
Zero-allocation JSON logger. Fluent API, extremely fast.
Viper
Configuration
Supports JSON, YAML, TOML, env vars, flags. Live config reload.
Cobra
CLI Framework
Powers kubectl, Hugo, GitHub CLI. Subcommands, flags, auto-completion.
5 Build & Deployment
Go compiles to a single static binary with no runtime dependencies. This makes deployment exceptionally simple β just copy the binary to the target machine.
Cross-Compilation
# Build for Linux (from macOS/Windows)
GOOS=linux GOARCH=amd64 go build -o myapp-linux .
# Build for Windows
GOOS=windows GOARCH=amd64 go build -o myapp.exe .
# Build for macOS ARM (Apple Silicon)
GOOS=darwin GOARCH=arm64 go build -o myapp-mac .
# Common GOOS/GOARCH combinations:
# linux/amd64 β most cloud servers
# linux/arm64 β ARM servers, AWS Graviton
# darwin/arm64 β macOS Apple Silicon
# darwin/amd64 β macOS Intel
# windows/amd64 β Windows 64-bit
Static Linking & Build Flags
# Fully static binary (no CGO dependencies)
CGO_ENABLED=0 go build -o myapp .
# Strip debug info for smaller binary
go build -ldflags="-s -w" -o myapp .
# Embed version info at build time
go build -ldflags="-X main.version=1.2.3 -X main.buildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)" -o myapp .
Docker Multi-Stage Build
# Dockerfile
FROM golang:1.24-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /app/server .
# Final image β from scratch (no OS, ~5MB total)
FROM scratch
COPY --from=builder /app/server /server
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
EXPOSE 8080
ENTRYPOINT ["/server"]
Why Go Deployment is Simple
- β’ Single binary β no runtime, no VM, no interpreter to install
- β’ Cross-compilation is a first-class feature β build Linux binaries on macOS
- β’ Docker images can be as small as 5β10MB using
FROM scratch - β’ Static linking means zero external library dependencies
6 VS Code and gopls imports guide
In daily Go work, the VS Code Go extension and gopls connect editor behavior with the Go toolchain. Organizing imports on save, removing unused imports, and adding missing imports are mostly controlled by source.organizeImports and the default formatter setting.
For exact configuration, read VS Code gopls organize imports.
6 Chapter Summary
Toolchain
build, run, test, fmt, vet, mod β all built-in
Testing
Table-driven tests, benchmarks, coverage reports
Code Quality
gofmt, go vet, golangci-lint, goimports
Ecosystem
Gin, GORM, zap, Viper, Cobra and more
Deployment
Cross-compilation, Docker multi-stage, static binaries
All-in-One
No Makefile, no external tools β just the go command
Loading comments...