Idiomatic Go 1.25+ development. Use when writing Go code, designing APIs, discussing Go patterns, or reviewing Go implementations. Emphasizes stdlib, concrete types, simple error handling, and minimal dependencies.
[TESTING.md](TESTING.md) - Testing strategies with testify/mockery
[CLI.md](CLI.md) - CLI application patterns
Tooling
go build ./... # Build
go test -race ./... # Test with race detector
golangci-lint run # Lint
mockery --all # Generate mocks
Gotchas
nil channel sends/receives block forever; closed channel receives return zero value immediately — select with a nil channel case disables that case, useful pattern but easy to do accidentally.
defer captures arguments at the call site, not at execution — defer fmt.Println(time.Now()) captures NOW, not the deferred time.
Pre-Go 1.22 for-loop variable capture closures over ONE variable across all iterations — the goroutine-in-loop bug. Go 1.22 changed semantics; old habits create subtle bugs in mixed-version code.
errors.Is walks Unwrap() chains, BUT if a wrapped error implements Is(target error) bool itself, that custom Is wins over walking — confusing when migrating from xerrors.
sync.Pool items can be GC'd between Get and the next Put — never rely on a Pool to retain state.