Write simple, explicit, concurrent Go. Small interfaces at the boundary; errors as values. HTTP Gin: golang-apis. Heavy concurrency: golang-goroutines. Tests: golang-unit-testing. Production: golang-production.
Tooling
- Go 1.25+ in new code; respect
godirective ofgo.mod. gofmt/goimports,go vet,go test ./....- Modules:
go get,go mod tidy; noreplaceforgotten in prod. golangci-lintif the CI already uses it — do not impose a new config in a feature.
Organization
cmd/myapp/main.go
internal/
...
pkg/ # só se API pública para outros módulos
go.mod
internal/for code that should not be imported outside the module.mainthin: flags/env, wiring,os.Exitaware.- Packages by domain, not by type (
models,utils).
Language
- Accept interfaces in the parameter; return concrete structs.
- Errors:
fmt.Errorf("...: %w", err); compare witherrors.Is/As. - Do not
_ = err. Sentinel (ErrNotFound) in the owning package. - Slices:
appendaliasing-aware;slices/mapsstdlib. - Iterators (
rangeover func) when the project's Go is already 1.23+ and it improves the API. iotafor closed enums; avoid magic strings at the boundary.- Useful zero value;
NewXwhen the invariant requires it.
type UserID string
func (id UserID) Validate() error {
if id == "" {
return fmt.Errorf("user id: %w", ErrInvalid)
}
return nil
}
Context
context.Contextfirst parameter in I/O and RPC.- Do not store ctx in a struct (except short, documented request-scoped).
- Derive with
WithCancel/WithTimeout; cancel on shutdown. - Values in ctx only for request-scoped (trace id), not for DI.
Concurrency (minimum)
- Do not start
gowithout a life plan (errgroup, wait, shutdown). - Do not share a map without a mutex. Race:
go test -race. - Detail:
golang-goroutines.
Tests and quality
- Table-driven in the
_test. - Fakes at the ports; httptest at the HTTP boundary.
- Skill:
golang-unit-testing.
Anti-patterns
panicin a lib due to user inputinit()with network I/O- Interface with 15 methods “just in case”
- Assume Gin/
gin.Contextin this skill interface{}/anywithout justification- Ignore
contextin an HTTP client
Integration with other skills
- Gin APIs:
golang-apis - Production:
golang-production - SQL:
golang-sqlc - gRPC:
grpc - Micro:
golang-microservices
Completion criteria
- Clear packages; errors wrapped
- ctx at the I/O boundaries
gofmt+vet; tests of the critical path- No panic on external input
- No imposed HTTP/SQL dependency