writing-go
Go Development (1.25+)
Core Philosophy
-
Stdlib and Mature Libraries First
- Always prefer Go stdlib solutions
- External deps only when stdlib is insufficient
- Choose mature, well-maintained libs when needed
- Don't reinvent the wheel—use existing solutions
-
Concrete Types Over
any- Never use
interface{}oranywhen concrete type works - Generics for reusable utilities, concrete types for business logic
- Accept interfaces, return structs
- Never use
-
Private Interfaces at Consumer
- Define interfaces private (lowercase) where used
- Decouples code, enables testing
- Implementation returns concrete types
-
Flat Control Flow
- Early returns, guard clauses
- No nested IFs—max 2 levels
- Switch for multi-case logic
-
Explicit Error Handling
- Always wrap with context
- Use
errors.Is()/errors.As() - No bare
return err
Quick Patterns
Private Interface at Consumer
// service/user.go - private interface where it's USED
type userStore interface {
Get(ctx context.Context, id string) (*User, error)
}
type Service struct {
store userStore // accepts interface
}
// repo/postgres.go - returns concrete type
func NewPostgresStore(db *sql.DB) *PostgresStore {
return &PostgresStore{db: db}
}
Flat Control Flow (No Nesting)
// GOOD: guard clauses, early returns
func process(user *User) error {
if user == nil {
return ErrNilUser
}
if user.Email == "" {
return ErrMissingEmail
}
if !isValidEmail(user.Email) {
return ErrInvalidEmail
}
return doWork(user)
}
// BAD: nested conditions
func process(user *User) error {
if user != nil {
if user.Email != "" {
if isValidEmail(user.Email) {
return doWork(user)
}
}
}
return nil
}
Error Handling
if err := doThing(); err != nil {
return fmt.Errorf("do thing: %w", err) // always wrap
}
// Sentinel errors
if errors.Is(err, ErrNotFound) {
return http.StatusNotFound
}
Concrete Types (Avoid any)
// GOOD: concrete types
func ProcessUsers(users []User) error { ... }
func GetUserByID(id string) (*User, error) { ... }
// BAD: unnecessary any
func ProcessItems(items []any) error { ... }
func GetByID(id any) (any, error) { ... }
Table-Driven Tests
tests := []struct {
name string
input string
want string
wantErr bool
}{
{"valid", "hello", "HELLO", false},
{"empty", "", "", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Process(tt.input)
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
assert.Equal(t, tt.want, got)
})
}
Go 1.25 Features
- testing/synctest: Deterministic concurrent testing
- encoding/json/v2: 3-10x faster (GOEXPERIMENT=jsonv2)
- runtime/trace.FlightRecorder: Production trace capture
- Container-aware GOMAXPROCS: Auto-detects cgroup limits
References
- PATTERNS.md - Detailed code patterns
- TESTING.md - Testing with testify/mockery
- CLI.md - CLI application patterns
Tooling
go build ./... # Build
go test -race ./... # Test with race detector
golangci-lint run # Lint
mockery --all # Generate mocks
More from alexei-led/claude-code-config
brainstorming-ideas
Turn ideas into designs through collaborative dialogue. Use when user wants to brainstorm, design features, explore approaches, or think through implementation before coding.
19refactoring-code
Batch refactoring via MorphLLM edit_file. Use for "refactor across files", "batch rename", "update pattern everywhere", large files (500+ lines), or 5+ edits in same file.
11testing-e2e
E2E testing with Playwright MCP for browser automation, test generation, and UI testing. Use when discussing E2E tests, Playwright, browser testing, UI automation, visual testing, or accessibility testing. Supports TypeScript tests and Go/HTMX web applications.
10writing-python
Idiomatic Python 3.14+ development. Use when writing Python code, CLI tools, scripts, or services. Emphasizes stdlib, type hints, uv/ruff toolchain, and minimal dependencies.
7looking-up-docs
Library documentation via Context7. Use for API references, code examples, framework docs.
7writing-typescript
Idiomatic TypeScript development. Use when writing TypeScript code, Node.js services, React apps, or discussing TS patterns. Emphasizes strict typing, composition, and modern tooling (bun/vite).
7