# Golang Idioms

Idiomatic Go patterns for error handling, interfaces, concurrency, testing, and module...

- Repository: https://github.com/rohitg00/awesome-claude-code-toolkit (2800 stars)
- Category: Testing
- License: Apache-2.0
- Last updated: 2026-05-12
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add rohitg00/awesome-claude-code-toolkit --skill golang-idioms -g -a claude-code -y`
Codex: `npx skills add rohitg00/awesome-claude-code-toolkit --skill golang-idioms -g -a codex -y`
Cursor: `npx skills add rohitg00/awesome-claude-code-toolkit --skill golang-idioms -g -a cursor -y`
Gemini CLI: `npx skills add rohitg00/awesome-claude-code-toolkit --skill golang-idioms -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add rohitg00/awesome-claude-code-toolkit`

## Description

Idiomatic Go patterns for error handling, interfaces, concurrency, testing, and module management

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Go Idioms

## Error Handling

```go
// Return errors, never panic in library code
func LoadConfig(path string) (Config, error) {
    data, err := os.ReadFile(path)
    if err != nil {
        return Config{}, fmt.Errorf("reading config %s: %w", path, err)
    }

    var cfg Config
    if err := json.Unmarshal(data, &cfg); err != nil {
        return Config{}, fmt.Errorf("parsing config: %w", err)
    }

    return cfg, nil
}
```

Rules:
- Always wrap errors with context using `fmt.Errorf("context: %w", err)`
- Use `%w` to allow callers to use `errors.Is` and `errors.As`
- Handle errors at the appropriate level; do not log and return the same error
- Define sentinel errors for expected conditions

```go
var (
    ErrNotFound    = errors.New("not found")
    ErrUnauthorized = errors.New("unauthorized")
)

func GetUser(id string) (User, error) {
    user, ok := store[id]
    if !ok {
        return User{}, fmt.Errorf("user %s: %w", id, ErrNotFound)
    }
    return user, nil
}

// Caller
user, err := GetUser(id)
if errors.Is(err, ErrNotFound) {
    http.Error(w, "user not found", http.StatusNotFound)
    return
}
```

## Interface Design

```go
// Keep interfaces small (1-3 methods)
type Reader interface {
    Read(p []byte) (n int, err error)
}

type UserStore interface {
    GetUser(ctx context.Context, id string) (User, error)
    CreateUser(ctx context.Context, u User) error
}

// Accept interfaces, return structs
func NewService(store UserStore, logger *slog.Logger) *Service {
    return &Service{store: store, logger: logger}
}
```

Rules:
- Define interfaces where they are used (consumer side), not where they are implemented
- Prefer small, composable interfaces over large ones
- Use `io.Reader`, `io.Writer`, `fmt.Stringer` from the standard library
- An interface with one method should be named after the method + `er` suffix

## Goroutine and Channel Patterns

The rest: https://github.com/rohitg00/awesome-claude-code-toolkit/blob/HEAD/skills/golang-idioms/SKILL.md
