Go style and best practices guide synthesized from Google, Uber, and official Go documentation. This skill should be used when writing, reviewing, or refactoring Go code. Triggers on tasks involving Go packages, error handling, concurrency, interfaces, or performance optimization.
Style and best practices guide for Go applications. Contains 60+ rules across 10 categories, synthesized from authoritative sources.
Core skill for: [[Dev]] (implementing Go code) and [[Architect]] (designing Go architectures).
Always run golangci-lint before completing any Go work:
# Run linter on all packages
golangci-lint run ./...
# Run with auto-fix for safe fixes
golangci-lint run --fix ./...
The project uses .golangci.yml which enables:
For reviews: Run linter first. Any issues found should be tracked as tasks using .
bd createReference these guidelines when:
This skill auto-activates when working with:
*.go, *_test.gofunc, type, interface, go func, chan, selectif err != nil| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | Error Handling | CRITICAL | err- |
| 2 | Naming & Style | HIGH | name- |
| 3 | Interfaces | HIGH | iface- |
| 4 | Concurrency | HIGH | conc- |
| 5 | Package Design | MEDIUM-HIGH | pkg- |
| 6 | Functions & Methods | MEDIUM | func- |
| 7 | Testing | MEDIUM | test- |
| 8 | Performance | MEDIUM | perf- |
| 9 | Documentation | LOW-MEDIUM | doc- |
| 10 | Project Structure | LOW | struct- |
err-handle - Always handle errors, never use _err-wrap - Wrap errors with context using fmt.Errorf("...: %w", err)err-types - Use sentinel errors or custom types for expected errorserr-strings - Error strings: lowercase, no punctuationerr-flow - Indent error handling, keep happy path unindentederr-panic - Don't panic for normal errors, only unrecoverable situationserr-inband - Avoid in-band errors; use multiple returnsname-mixedcaps - Use MixedCaps, not underscoresname-initialisms - Keep initialisms uppercase: URL, HTTP, IDname-short - Short names for short scopes (i, r, ctx)name-receivers - Receiver names: 1-2 letters, consistent across methodsname-getters - No Get prefix for getters (Name() not GetName())name-packages - Package names: short, lowercase, singularname-avoid - Avoid util, common, misc, base package namesiface-consumer - Define interfaces where used, not where implementediface-small - Prefer small interfaces (1-3 methods)iface-accept - Accept interfaces, return concrete typesiface-verify - Verify interface compliance at compile timeiface-no-mock - Don't define interfaces just for mockingconc-goroutine-lifetime - Document when/whether goroutines exitconc-channel-ownership - Establish clear channel ownershipconc-prefer-sync - Prefer synchronous functions over asyncconc-mutex-embed - Embed mutex, don't expose itconc-context-first - Context as first parameterconc-no-context-struct - Don't store context in structspkg-single-purpose - One package, one purposepkg-internal - Use internal/ for private packagespkg-avoid-init - Avoid init() when possiblepkg-import-blank - Side-effect imports only in mainpkg-circular - Avoid circular dependenciesfunc-receiver-type - Use pointer receiver for mutations, large structsfunc-named-returns - Use named returns only for documentationfunc-naked-returns - Avoid naked returns except in tiny functionsfunc-options - Use functional options for complex configurationfunc-pass-values - Don't pass pointers to small immutable typestest-table-driven - Use table-driven teststest-useful-failures - Test failures should say: got X, want Ytest-examples - Write testable Example functionstest-parallel - Use t.Parallel() for independent teststest-helpers - Use t.Helper() in test helper functionstest-subtests - Use t.Run() for subtestsperf-preallocate - Preallocate slices when size is knownperf-strings-builder - Use strings.Builder for concatenationperf-sync-pool - Use sync.Pool for frequently allocated objectsperf-avoid-reflect - Avoid reflection in hot pathsperf-benchmark - Benchmark before optimizingdoc-package - Every package needs a package commentdoc-exported - Document all exported namesdoc-sentences - Comments are full sentences, start with namedoc-examples - Include runnable examples in docsstruct-cmd - Main packages in cmd/struct-internal - Private code in internal/struct-file-size - Keep files under 400 lines when practicalstruct-pkg-flat - Prefer flat package structure over deep nestingQuick lookup: Reference the rule name from the Quick Reference above, then read the detailed rule:
rules/{rule-name}.md
Example: For err-wrap, read rules/err-wrap.md
Each rule file contains:
Full document: For the complete guide with all rules expanded: AGENTS.md
When implementing Go tasks:
When designing Go architectures: