Google Go Best Practices
Comprehensive Go coding guide based on Google's internal style guide. Contains 47 rules across 8 categories, prioritized by impact to guide code review, refactoring, and generation.
When to Apply
Reference these guidelines when:
- Writing new Go packages, functions, or methods
- Reviewing Go code for style and correctness
- Refactoring existing Go code
- Designing Go APIs (interfaces, option patterns, error types)
- Writing or improving Go tests
Rule Categories by Priority
| Priority |
Category |
Impact |
Guide |
| 1 |
Naming |
CRITICAL |
rules/naming.md |
| 2 |
Error Handling |
CRITICAL |
rules/error.md |
| 3 |
Design Patterns |
HIGH |
rules/design.md |
| 4 |
Formatting |
HIGH |
rules/format.md |
| 5 |
Documentation |
MEDIUM |
rules/doc.md |
| 6 |
Testing |
MEDIUM |
rules/testing.md |
| 7 |
Concurrency |
MEDIUM |
rules/concurrency.md |
| 8 |
Performance |
LOW-MEDIUM |
rules/perf.md |
Quick Reference
1. Naming (CRITICAL) — See rules/naming.md
- Avoid Redundant Naming — don't repeat package, receiver, parameter, or return type info
- Package Naming — short, lowercase, no underscores; avoid
util, helper, common
- Receiver Naming — one or two letter abbreviation, consistent across methods
- Constant Naming — MixedCaps only; no ALL_CAPS or k-prefix; name by role not value
- Acronym Casing — consistent:
URL/url, ID/id, never Url or Id
- No Get Prefix — use nouns for accessors, verbs for actions
- Variable Naming — length proportional to scope; omit type info
- Function Naming — nouns for return-value functions, verbs for actions
2. Error Handling (CRITICAL) — See rules/error.md
- Structured Errors — use sentinel values or typed errors, not string matching
- Add Non-Redundant Context — meaningful wrapping without duplication
- %v vs %w —
%v at boundaries, %w for programmatic inspection
- %w Position — place at end:
"context: %w"
- Return error Interface — not concrete types
- Handle Errors Explicitly — never silently discard with
_
- Indent Error Flow — handle errors first, keep success path unindented
- Avoid In-Band Errors — use multiple returns instead of special values
- Error Logging — don't double-log; guard expensive log calls
3. Design Patterns (HIGH) — See rules/design.md
- Interfaces Belong to Consumers — define in consumer, return concrete from producer
- Option Structs — for many callers needing many params
- Variadic Options — functional options when most callers need no config
- Avoid Global State — provide instance-based APIs
- Pass Values — not pointers for small fixed-size types
- Receiver Types — pointer for mutation/large; value for small immutable
- Generics — use only when genuinely needed
- Context Conventions — always first param, never in structs
4. Formatting (HIGH) — See rules/format.md
- Always gofmt — use
gofmt or goimports
- Import Grouping — stdlib, third-party, proto, side-effect
- Import Renaming — only for conflicts; proto uses
pb suffix
- Struct Literal Fields — use field names; omit zero values
- Nil Slices — prefer
var t []string over t := []string{}
- Function Formatting — keep signatures on one line; extract locals
- Variable Declarations —
:= for non-zero, var for zero, new() for pointers
- Conditions — extract complex conditions; no Yoda; no redundant
break
5. Documentation (MEDIUM) — See rules/doc.md
- Doc Comments — exported names start with symbol name as complete sentence
- Package Comments — one per package above
package clause
- Parameter Docs — only document non-obvious parameters
- Cleanup Docs — document cleanup requirements and error sentinels
- Signal Boosting — add comments for code that looks standard but isn't
6. Testing (MEDIUM) — See rules/testing.md
- Table-Driven Tests — with named fields and descriptions
- No Assertion Libraries —
testing package only
- Got Before Want — format:
Func(%v) = %v, want %v
- Test Helpers — call
t.Helper(); prefix must-succeed with must
- Scoped Setup — explicit per test; no package-level
init()
- Error Semantics — test with
errors.Is, not strings
- Goroutine Fatal — use
t.Error not t.Fatal from goroutines
7. Concurrency (MEDIUM) — See rules/concurrency.md
- Goroutine Lifetimes — use WaitGroup to bound lifetimes
- Synchronous Functions — prefer sync; callers add concurrency
- Channel Direction — specify
<-chan or chan<- in signatures
- No Copy — never copy
sync.Mutex or types with pointer methods
- No Panic — use errors for normal failures; panic only for invariants
- Variable Shadowing — watch for
:= shadowing in inner scopes
8. Performance (LOW-MEDIUM) — See rules/perf.md
- String Concatenation —
+ for simple, Sprintf for format, Builder for loops
- Size Hints — pre-allocate with justified hints only
- %q Format — use for readable string output
- crypto/rand — for keys, never
math/rand
- Use any — instead of
interface{} in new code
Full Compiled Document
For the complete guide with all rules expanded: AGENTS.md
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: go-best-practices-23description: Google Go coding best practices and style guide for writing idiomatic, maintainable Go code. Use when writing, reviewing, or refactoring Go code. Triggers on Go naming conventions, error handling patterns, interface design, testing structure, concurrency patterns, formatting, and documentation. Use when this capability is needed.4---567# Google Go Best Practices89Comprehensive Go coding guide based on Google's internal style guide. Contains 47 rules across 8 categories, prioritized by impact to guide code review, refactoring, and generation.1011## When to Apply1213Reference these guidelines when:14- Writing new Go packages, functions, or methods15- Reviewing Go code for style and correctness16- Refactoring existing Go code17- Designing Go APIs (interfaces, option patterns, error types)18- Writing or improving Go tests1920## Rule Categories by Priority2122| Priority | Category | Impact | Guide |23|----------|----------|--------|-------|24| 1 | Naming | CRITICAL | [rules/naming.md](rules/naming.md) |25| 2 | Error Handling | CRITICAL | [rules/error.md](rules/error.md) |26| 3 | Design Patterns | HIGH | [rules/design.md](rules/design.md) |27| 4 | Formatting | HIGH | [rules/format.md](rules/format.md) |28| 5 | Documentation | MEDIUM | [rules/doc.md](rules/doc.md) |29| 6 | Testing | MEDIUM | [rules/testing.md](rules/testing.md) |30| 7 | Concurrency | MEDIUM | [rules/concurrency.md](rules/concurrency.md) |31| 8 | Performance | LOW-MEDIUM | [rules/perf.md](rules/perf.md) |3233## Quick Reference3435### 1. Naming (CRITICAL) — See [rules/naming.md](rules/naming.md)3637- Avoid Redundant Naming — don't repeat package, receiver, parameter, or return type info38- Package Naming — short, lowercase, no underscores; avoid `util`, `helper`, `common`39- Receiver Naming — one or two letter abbreviation, consistent across methods40- Constant Naming — MixedCaps only; no ALL_CAPS or k-prefix; name by role not value41- Acronym Casing — consistent: `URL`/`url`, `ID`/`id`, never `Url` or `Id`42- No Get Prefix — use nouns for accessors, verbs for actions43- Variable Naming — length proportional to scope; omit type info44- Function Naming — nouns for return-value functions, verbs for actions4546### 2. Error Handling (CRITICAL) — See [rules/error.md](rules/error.md)4748- Structured Errors — use sentinel values or typed errors, not string matching49- Add Non-Redundant Context — meaningful wrapping without duplication50- %v vs %w — `%v` at boundaries, `%w` for programmatic inspection51- %w Position — place at end: `"context: %w"`52- Return error Interface — not concrete types53- Handle Errors Explicitly — never silently discard with `_`54- Indent Error Flow — handle errors first, keep success path unindented55- Avoid In-Band Errors — use multiple returns instead of special values56- Error Logging — don't double-log; guard expensive log calls5758### 3. Design Patterns (HIGH) — See [rules/design.md](rules/design.md)5960- Interfaces Belong to Consumers — define in consumer, return concrete from producer61- Option Structs — for many callers needing many params62- Variadic Options — functional options when most callers need no config63- Avoid Global State — provide instance-based APIs64- Pass Values — not pointers for small fixed-size types65- Receiver Types — pointer for mutation/large; value for small immutable66- Generics — use only when genuinely needed67- Context Conventions — always first param, never in structs6869### 4. Formatting (HIGH) — See [rules/format.md](rules/format.md)7071- Always gofmt — use `gofmt` or `goimports`72- Import Grouping — stdlib, third-party, proto, side-effect73- Import Renaming — only for conflicts; proto uses `pb` suffix74- Struct Literal Fields — use field names; omit zero values75- Nil Slices — prefer `var t []string` over `t := []string{}`76- Function Formatting — keep signatures on one line; extract locals77- Variable Declarations — `:=` for non-zero, `var` for zero, `new()` for pointers78- Conditions — extract complex conditions; no Yoda; no redundant `break`7980### 5. Documentation (MEDIUM) — See [rules/doc.md](rules/doc.md)8182- Doc Comments — exported names start with symbol name as complete sentence83- Package Comments — one per package above `package` clause84- Parameter Docs — only document non-obvious parameters85- Cleanup Docs — document cleanup requirements and error sentinels86- Signal Boosting — add comments for code that looks standard but isn't8788### 6. Testing (MEDIUM) — See [rules/testing.md](rules/testing.md)8990- Table-Driven Tests — with named fields and descriptions91- No Assertion Libraries — `testing` package only92- Got Before Want — format: `Func(%v) = %v, want %v`93- Test Helpers — call `t.Helper()`; prefix must-succeed with `must`94- Scoped Setup — explicit per test; no package-level `init()`95- Error Semantics — test with `errors.Is`, not strings96- Goroutine Fatal — use `t.Error` not `t.Fatal` from goroutines9798### 7. Concurrency (MEDIUM) — See [rules/concurrency.md](rules/concurrency.md)99100- Goroutine Lifetimes — use WaitGroup to bound lifetimes101- Synchronous Functions — prefer sync; callers add concurrency102- Channel Direction — specify `<-chan` or `chan<-` in signatures103- No Copy — never copy `sync.Mutex` or types with pointer methods104- No Panic — use errors for normal failures; panic only for invariants105- Variable Shadowing — watch for `:=` shadowing in inner scopes106107### 8. Performance (LOW-MEDIUM) — See [rules/perf.md](rules/perf.md)108109- String Concatenation — `+` for simple, `Sprintf` for format, `Builder` for loops110- Size Hints — pre-allocate with justified hints only111- %q Format — use for readable string output112- crypto/rand — for keys, never `math/rand`113- Use any — instead of `interface{}` in new code114115## Full Compiled Document116117For the complete guide with all rules expanded: [AGENTS.md](AGENTS.md)118119---120> Converted and distributed by [TomeVault](https://tomevault.io/claim/kaptinlin) — claim your Tome and manage your conversions.121<!-- tomevault:4.0:skill_md:2026-04-11 -->