| name | go-styleguide |
| description | Use when writing, editing, or reviewing Go (.go) source in a dexpace project — enforces the dexpace Go styleguide (errors as values, structs + functions, bounded concurrency, 70-line function cap). Also use before committing Go, or when asked to review Go against the styleguide. |
Go styleguide
Extends the Google Go Style Guide; where they conflict, Google wins, except the deviations below.
When this applies
Editing *.go, or reviewing Go. Priority: correctness > performance > developer experience.
Non-negotiables
- Data + functions: structs for state, functions and small interfaces for behavior. No inheritance, no embedding for "is-a".
- Explicit over implicit: every dependency in the signature, every error returned. Library options follow documented defaults.
- Immutable by default: return new values; no mutating shared state; read-only intent at API edges.
- Errors are values: handle every path. No
_ = err. Wrap with %w plus context (cause, inputs, correlation ID).
- Composition over inheritance: small consumer-defined interfaces composed together.
- Transform, don't mutate: input in, new output out; state changes localized and visible.
- Always say why: comments explain reasoning, not mechanics.
- Assert aggressively: ≥2 assertions per function on average; preconditions, postconditions, invariants; split compound checks.
- Limits on everything: bound every loop, channel, retry, buffer, timeout. No recursion in library code.
- Small functions: one thing each; 70-line hard cap, aim 20–40; blank lines between logical sections.
- Performance from the outset: work with the runtime's grain; optimize slowest resource first (network > disk > memory > CPU).
- Zero technical debt: do it right the first time.
Language hard rules
%w for wrapping, one level; place it at the end of the format string.
- No in-band errors (no sentinel
-1/"" for "not found") — return an explicit error or a typed result.
- Error strings lowercase, no trailing punctuation.
context.Context is the first parameter, named ctx; never store it in a struct; no custom context types.
- Prefer synchronous APIs; the caller adds concurrency. Every goroutine has a known lifetime and a way to stop.
- Accept interfaces, return structs; interfaces defined by the consumer, kept small.
gofmt and golangci-lint are law. t.Fatal only from the test goroutine.
crypto/rand for secrets; never math/rand. defer for cleanup; timeouts on all external I/O.
Before you finish — verify
gofmt -l .
golangci-lint run
go vet ./...
go test ./...
Full guide
Deep review
For a full audit (not a quick edit), read reference/checklist.md in this skill and walk every chapter.