Go Patterns
This skill focuses on idiomatic Go design and code review guidance.
If your task is primarily measurement/profiling/optimization, use golang-performance.
When to activate
- Writing new Go code (packages, APIs, services)
- Reviewing PRs for idioms, readability, and maintainability
- Refactoring for cleaner error handling and smaller interfaces
- Designing concurrency flows with cancellation and backpressure
- Choosing a dispatch/plugin mechanism, adding modules to a compiled binary, or building low-level/offensive Go tooling
Core principles (high signal)
- gofmt is non-negotiable. Style debates end at
gofmt. - Prefer clarity: small functions, early returns, explicit control flow.
- Make the zero value useful.
- Keep interfaces small; define them where they’re consumed.
- Handle errors explicitly; wrap with context; avoid
panicfor control flow. - Concurrency should be bounded and cancellable; avoid goroutine leaks.
Outcome expectations
- Public APIs are small, explicit, and boring to maintain.
- Error handling is consistent and machine-checkable with
errors.Is/errors.AsType. - Concurrency flows always have cancellation and backpressure.
- Tooling baseline (
gofmt, tests, vet/race) is easy to run in CI.
Recommended workflow
- Define package boundary + API contracts (inputs, outputs, errors) first.
- Implement with small functions and explicit control flow.
- Add context propagation and cancellation checks on blocking operations.
- Run formatting/tests/vet/race before review.
- Review for leaks, hidden globals, and interface over-abstraction.
Quick review checklist
- Naming: MixedCaps for exported, no underscores, packages short and lower-case
- Errors:
fmt.Errorf("context: %w", err),errors.Is/errors.AsType(Go 1.26+) used correctly - Context:
ctxis first param; cancellation propagates; nocontext.Contextstored in structs - Interfaces: accept interfaces, return concrete types; no “kitchen-sink” interfaces
- Concurrency: goroutines have a stop condition; channels are closed by senders; backpressure exists
- Tooling:
go test ./...,go test -race ./...,go vet ./...
Common anti-patterns to reject
- Storing
context.Contextin structs - Unbounded goroutine fan-out in request paths
- Catch-all interfaces like
Doer,Manager,Servicewithout clear boundary - Returning wrapped errors without enough domain context
- Package-level mutable state hidden behind helper functions
Resources
Load on demand (progressive disclosure):
references/effective-go.md— distilled Effective Go + Code Review Comments pointersreferences/language.md— load when using loop-var/range-over-func semantics,new(expr), self-referential constraints, generic methods, embedded-field keys, or 1.27 type inferencereferences/json-v2.md— load when adding or migrating JSON (encoding/jsonvsencoding/json/v2,omitzero, stricter defaults)references/errors.md— wrapping, sentinel vs typed errors,errors.AsType, validation, retryable errorsreferences/interfaces.md— interface placement, design patterns, optional behavior, generic-method vs interface-method rulereferences/concurrency.md— cancellation, errgroup, leaks, worker pools, backpressure, timer-channel semanticsreferences/api-and-structs.md— receiver rules, functional options, embedding, ServeMux patternsreferences/package-layout.md— project layout, package naming, dependency injectionreferences/tooling.md— gofmt/goimports, vet,go fix, language version via thegodirectivereferences/security-review.md— use when auditing Go for security bugs: untrusted input, panics/DoS, TLS defaults, secrets, supply chain (govulncheck,gosec)references/unsafe-cgo.md— use forunsafe.Pointerrules,syscall/x/sys, cgo boundaries, and static/cross-compiled offensive-tooling buildsreferences/dispatch-and-plugins.md— use when choosingdyninterfaces vs enum dispatch, building registries and command dispatchers, or adding modules to a compiled binary (plugin,hashicorp/go-plugin,wazero/extism,yaegi,selfupdate,tableflip)references/offensive-lowlevel.md— use for RE-resistance, symbol/metadata stripping,garble/GoReSym, string obfuscation, syscall dispatch strategy, and in-memory execution