Go Development Patterns
Idiomatic Go patterns and best practices for building robust, efficient, and maintainable applications. Based on Effective Go, Go Code Review Comments, Uber Go Style Guide, and Google Go Style Guide.
Quick Start
- Concurrency needed? → Concurrency Patterns reference, check CRITICAL Rules #1-#5
- Using Go 1.21+ features? → Modern Go reference (slog, iterators, ServeMux, generics)
- Writing tests? → Testing Patterns reference (table-driven, fuzz, benchmarks)
- Error handling? → See Error Handling below
- Package design? → See Package Organization below
When to Activate
- Writing new Go code
- Reviewing or refactoring Go code
- Designing Go packages/modules
- Implementing concurrency patterns
- Building HTTP services with net/http
- Writing tests, benchmarks, or fuzz tests
- Using generics or iterators
CRITICAL Rules
MUST DO
- Handle every error — Never use
_ for errors unless explicitly justified with comment
- Wrap errors with context —
fmt.Errorf("operation %s: %w", name, err) always
- Pass context.Context as first param — Never store in struct fields
- Use structured concurrency — Every goroutine must have clear ownership and shutdown path
- Close resources with defer —
defer f.Close() immediately after successful open
- Accept interfaces, return structs — Define interfaces at consumer, not provider
- Make zero values useful — Design types to work without explicit initialization
- Format with gofmt/goimports — Non-negotiable, run before every commit
- Preallocate slices —
make([]T, 0, knownLen) when capacity is known
- Use
errors.Is/errors.As — Never compare errors with == (except sentinel errors pre-1.13)
MUST NOT DO
panic for control flow — Only for truly unrecoverable programmer errors
- Naked returns in long functions — Only acceptable in very short functions (< 5 lines)
init() with side effects — Avoid init(); prefer explicit initialization via constructors
- Global mutable state — Use dependency injection instead of package-level vars
- Goroutine leaks — Always provide cancellation path (context, done channel, or buffered channel)
sync.Mutex copying — Never copy a Mutex; embed as pointer or use pointer receiver
interface{} when generics fit — Use type parameters for type-safe collections (Go 1.18+)
- Log AND return error — Handle errors once: either log or return, never both (Uber Guide)
math/rand for security — Use crypto/rand for keys, tokens, and secrets
fmt.Sprintf for int-to-string — Use strconv.Itoa/strconv.FormatInt (3x faster)
Reference Guide
Load detailed guidance based on context:
| Topic |
Reference |
Load When |
| Concurrency |
references/concurrency-patterns.md |
goroutines, channels, sync, errgroup, context, graceful shutdown |
| Modern Go (1.21-1.23+) |
references/modern-go.md |
slog, iterators, enhanced ServeMux, generics, range-over-int |
| Testing |
references/testing-patterns.md |
table-driven tests, fuzz, benchmarks, mocking, golden files, HTTP handler tests |
Decision Tree
Writing Go code?
├─ Error handling?
│ ├─ Known error condition → sentinel error (var ErrXxx = errors.New(...))
│ ├─ Error needs context → fmt.Errorf("context: %w", err)
│ ├─ Multiple errors → errors.Join (Go 1.20+)
│ └─ Rich error info needed → custom error type implementing error interface
├─ Concurrency needed?
│ ├─ Fire-and-forget task → references/concurrency-patterns.md (Worker Pool)
│ ├─ Multiple concurrent ops → errgroup.Group
│ ├─ Shared state → sync.Mutex or channel
│ ├─ Cancellation/timeout → context.WithCancel / WithTimeout
│ └─ Graceful shutdown → signal.Notify + context
├─ HTTP service?
│ ├─ Method + path routing → Enhanced ServeMux (references/modern-go.md)
│ ├─ Middleware pattern → func(http.Handler) http.Handler
│ └─ Structured logging → slog (references/modern-go.md)
├─ Type-safe collection?
│ ├─ Simple generic func → references/modern-go.md (Generics)
│ ├─ Iterator pattern → iter.Seq / iter.Seq2 (Go 1.23+)
│ └─ Type constraint → interface with ~type union
├─ Testing?
│ ├─ Multiple inputs → Table-driven tests
│ ├─ Input validation → Fuzz tests
│ ├─ Performance measurement → Benchmarks
│ └─ Expected output files → Golden files
└─ Configuration?
├─ Many optional params → Functional Options pattern
├─ Simple required params → Constructor function
└─ External config → struct + json/yaml/env tags
Verification
코드 작성 후 반드시 실행:
go build ./... # 컴파일 확인
go test ./... -v # 테스트 실행
go vet ./... # 정적 분석
golangci-lint run # 린터 (설치된 경우)
Output Template
When implementing Go features, provide:
- Package structure and organization
- Core types (structs, interfaces, error types)
- Implementation with proper error handling
- Test file with table-driven tests
- Brief explanation of Go-specific patterns used
Source: sskim91/dotfiles — distributed by TomeVault.
1---2name: golang-patterns-53description: Use when writing or refactoring Go code, designing packages, implementing concurrency, using generics, or building HTTP services. Do NOT use for database optimization (use sql-optimization-patterns), API design (use api-design), or CI/CD (use github-actions).4---56# Go Development Patterns78Idiomatic Go patterns and best practices for building robust, efficient, and maintainable applications. Based on Effective Go, Go Code Review Comments, Uber Go Style Guide, and Google Go Style Guide.910## Quick Start1112- **Concurrency needed?** → [Concurrency Patterns reference](references/concurrency-patterns.md), check CRITICAL Rules #1-#513- **Using Go 1.21+ features?** → [Modern Go reference](references/modern-go.md) (slog, iterators, ServeMux, generics)14- **Writing tests?** → [Testing Patterns reference](references/testing-patterns.md) (table-driven, fuzz, benchmarks)15- **Error handling?** → See [Error Handling](#error-handling) below16- **Package design?** → See [Package Organization](#package-organization) below1718## When to Activate1920- Writing new Go code21- Reviewing or refactoring Go code22- Designing Go packages/modules23- Implementing concurrency patterns24- Building HTTP services with net/http25- Writing tests, benchmarks, or fuzz tests26- Using generics or iterators2728## CRITICAL Rules2930### MUST DO31321. **Handle every error** — Never use `_` for errors unless explicitly justified with comment332. **Wrap errors with context** — `fmt.Errorf("operation %s: %w", name, err)` always343. **Pass context.Context as first param** — Never store in struct fields354. **Use structured concurrency** — Every goroutine must have clear ownership and shutdown path365. **Close resources with defer** — `defer f.Close()` immediately after successful open376. **Accept interfaces, return structs** — Define interfaces at consumer, not provider387. **Make zero values useful** — Design types to work without explicit initialization398. **Format with gofmt/goimports** — Non-negotiable, run before every commit409. **Preallocate slices** — `make([]T, 0, knownLen)` when capacity is known4110. **Use `errors.Is`/`errors.As`** — Never compare errors with `==` (except sentinel errors pre-1.13)4243### MUST NOT DO44451. **`panic` for control flow** — Only for truly unrecoverable programmer errors462. **Naked returns in long functions** — Only acceptable in very short functions (< 5 lines)473. **`init()` with side effects** — Avoid init(); prefer explicit initialization via constructors484. **Global mutable state** — Use dependency injection instead of package-level vars495. **Goroutine leaks** — Always provide cancellation path (context, done channel, or buffered channel)506. **`sync.Mutex` copying** — Never copy a Mutex; embed as pointer or use pointer receiver517. **`interface{}` when generics fit** — Use type parameters for type-safe collections (Go 1.18+)528. **Log AND return error** — Handle errors once: either log or return, never both (Uber Guide)539. **`math/rand` for security** — Use `crypto/rand` for keys, tokens, and secrets5410. **`fmt.Sprintf` for int-to-string** — Use `strconv.Itoa`/`strconv.FormatInt` (3x faster)5556## Reference Guide5758Load detailed guidance based on context:5960| Topic | Reference | Load When |61|-------|-----------|-----------|62| Concurrency | [references/concurrency-patterns.md](references/concurrency-patterns.md) | goroutines, channels, sync, errgroup, context, graceful shutdown |63| Modern Go (1.21-1.23+) | [references/modern-go.md](references/modern-go.md) | slog, iterators, enhanced ServeMux, generics, range-over-int |64| Testing | [references/testing-patterns.md](references/testing-patterns.md) | table-driven tests, fuzz, benchmarks, mocking, golden files, HTTP handler tests |6566## Decision Tree6768```69Writing Go code?70├─ Error handling?71│ ├─ Known error condition → sentinel error (var ErrXxx = errors.New(...))72│ ├─ Error needs context → fmt.Errorf("context: %w", err)73│ ├─ Multiple errors → errors.Join (Go 1.20+)74│ └─ Rich error info needed → custom error type implementing error interface75├─ Concurrency needed?76│ ├─ Fire-and-forget task → references/concurrency-patterns.md (Worker Pool)77│ ├─ Multiple concurrent ops → errgroup.Group78│ ├─ Shared state → sync.Mutex or channel79│ ├─ Cancellation/timeout → context.WithCancel / WithTimeout80│ └─ Graceful shutdown → signal.Notify + context81├─ HTTP service?82│ ├─ Method + path routing → Enhanced ServeMux (references/modern-go.md)83│ ├─ Middleware pattern → func(http.Handler) http.Handler84│ └─ Structured logging → slog (references/modern-go.md)85├─ Type-safe collection?86│ ├─ Simple generic func → references/modern-go.md (Generics)87│ ├─ Iterator pattern → iter.Seq / iter.Seq2 (Go 1.23+)88│ └─ Type constraint → interface with ~type union89├─ Testing?90│ ├─ Multiple inputs → Table-driven tests91│ ├─ Input validation → Fuzz tests92│ ├─ Performance measurement → Benchmarks93│ └─ Expected output files → Golden files94└─ Configuration?95 ├─ Many optional params → Functional Options pattern96 ├─ Simple required params → Constructor function97 └─ External config → struct + json/yaml/env tags98```99100## Verification101102코드 작성 후 반드시 실행:103```bash104go build ./... # 컴파일 확인105go test ./... -v # 테스트 실행106go vet ./... # 정적 분석107golangci-lint run # 린터 (설치된 경우)108```109110## Output Template111112When implementing Go features, provide:1131141. Package structure and organization1152. Core types (structs, interfaces, error types)1163. Implementation with proper error handling1174. Test file with table-driven tests1185. Brief explanation of Go-specific patterns used119120---121> Source: [sskim91/dotfiles](https://github.com/sskim91/dotfiles) — distributed by [TomeVault](https://tomevault.io).122<!-- tomevault:4.0:skill_md:2026-06-16 -->