Go Best Practices
Apply distinguished-engineer Go judgment, held to the Google Go Style Guide bar, by default on any
Go work. Google's five principles in priority order: Clarity > Simplicity > Concision >
Maintainability > Consistency — when they conflict, the higher one wins.
How to use this skill
- Read
go-guidelines.md in this skill directory — it is the full ruleset (the single source
of truth). Apply it to whatever Go task is at hand. For concrete before/after patterns to imitate
(error wrapping, receiver consistency, table tests with go-cmp, options, goroutine lifetime),
read examples.md.
- Match the surrounding codebase's existing conventions where they conflict with a stylistic
preference here; apply the correctness/concurrency/error rules regardless.
- Before declaring Go work complete, ensure these pass and report honestly if any don't:
gofmt/goimports · go vet ./... · go build ./... · go test -race ./... · golangci-lint run.
The essentials (full rationale in go-guidelines.md)
- Clarity over cleverness; simplest design that works. Add abstraction only on real, proven need.
- Errors are values. Handle every one; wrap with
fmt.Errorf("...: %w", err) (lowercase, no
"failed to"); inspect with errors.Is/errors.As. Libraries return errors — they don't log or panic.
- Every goroutine needs an owner and a guaranteed exit. Plumb
context.Context (first arg) for
I/O/blocking work; bound concurrency; go test -race is mandatory.
- Accept interfaces, return concrete types. Define small interfaces at the consumer, not next to
the implementation. No interfaces "just in case."
- Idiomatic naming: MixedCaps, initialisms keep case (
userID, apiURL), no stutter, getters
omit Get. gofmt is non-negotiable.
- Make the zero value useful; mind nil-map writes and slice aliasing; set timeouts on all network
calls;
defer Close/cancel and check writer Close errors.
- Tests are table-driven, behavior-focused,
t.Run/t.Parallel, race-clean, no time/rand flakiness.
- Security: validate external input,
crypto/rand for secrets, parameterize SQL, never log secrets.
When reviewing a Go diff, use the review checklist at the end of go-guidelines.md.
1---2name: go-best-practices3description: World-class Go guidelines aligned to the Google Go Style Guide (Style Guide, Style Decisions, Best Practices) plus community consensus, for writing, reviewing, and refactoring Go. Use whenever working in a Go codebase (.go files, go.mod) — authoring packages/APIs, handling errors, concurrency/goroutines/context, interfaces, testing, performance, or reviewing a Go diff/PR. Covers Google's clarity>simplicity>concision>maintainability>consistency hierarchy, naming/receiver/error decisions, %w wrapping, goroutine lifecycle, table-driven tests with go-cmp, and a review checklist.4---56# Go Best Practices78Apply distinguished-engineer Go judgment, **held to the Google Go Style Guide bar**, by default on any9Go work. Google's five principles in priority order: **Clarity > Simplicity > Concision >10Maintainability > Consistency** — when they conflict, the higher one wins.1112## How to use this skill13141. **Read `go-guidelines.md`** in this skill directory — it is the full ruleset (the single source15 of truth). Apply it to whatever Go task is at hand. For concrete before/after patterns to imitate16 (error wrapping, receiver consistency, table tests with `go-cmp`, options, goroutine lifetime),17 read **`examples.md`**.182. Match the surrounding codebase's existing conventions where they conflict with a stylistic19 preference here; apply the correctness/concurrency/error rules regardless.203. Before declaring Go work complete, ensure these pass and report honestly if any don't:21 `gofmt`/`goimports` · `go vet ./...` · `go build ./...` · `go test -race ./...` · `golangci-lint run`.2223## The essentials (full rationale in `go-guidelines.md`)2425- **Clarity over cleverness; simplest design that works.** Add abstraction only on real, proven need.26- **Errors are values.** Handle every one; wrap with `fmt.Errorf("...: %w", err)` (lowercase, no27 "failed to"); inspect with `errors.Is`/`errors.As`. Libraries return errors — they don't log or panic.28- **Every goroutine needs an owner and a guaranteed exit.** Plumb `context.Context` (first arg) for29 I/O/blocking work; bound concurrency; `go test -race` is mandatory.30- **Accept interfaces, return concrete types.** Define small interfaces at the consumer, not next to31 the implementation. No interfaces "just in case."32- **Idiomatic naming:** MixedCaps, initialisms keep case (`userID`, `apiURL`), no stutter, getters33 omit `Get`. `gofmt` is non-negotiable.34- **Make the zero value useful;** mind nil-map writes and slice aliasing; set timeouts on all network35 calls; `defer` Close/cancel and check writer `Close` errors.36- **Tests are table-driven**, behavior-focused, `t.Run`/`t.Parallel`, race-clean, no time/rand flakiness.37- **Security:** validate external input, `crypto/rand` for secrets, parameterize SQL, never log secrets.3839When reviewing a Go diff, use the review checklist at the end of `go-guidelines.md`.