From go
Idiomatic Go: error wrapping with %w, context propagation, slog, generics, goroutines/channels, table-driven tests. Use when writing, reviewing, or refactoring .go files or projects with go.mod.
npx claudepluginhub christopherdavenport/christopherdavenport-marketplace --plugin goThis skill uses the workspace's default tool permissions.
Go's design rewards simplicity, composition, explicit error handling, and small interfaces. This skill steers Claude toward code that satisfies the major community style guides — Effective Go, Google's Go Style, Uber's Go Style, and the Go Code Review Comments — while incorporating modern stdlib idioms (`errors.Is`/`As` wrapping, `context.Context`, `log/slog`, generics, fuzz tests).
references/concurrency.mdreferences/control-flow.mdreferences/errors.mdreferences/formatting-and-comments.mdreferences/functions-and-methods.mdreferences/generics.mdreferences/interfaces-and-embedding.mdreferences/logging-and-observability.mdreferences/modules-and-tooling.mdreferences/naming.mdreferences/project-layout.mdreferences/slices-maps-strings.mdreferences/stdlib-patterns.mdreferences/structs-and-composites.mdreferences/testing.mdApplies Acme Corporation brand guidelines including colors, fonts, layouts, and messaging to generated PowerPoint, Excel, and PDF documents.
Guides strict Test-Driven Development (TDD): write failing tests first for features, bugfixes, refactors before any production code. Enforces red-green-refactor cycle.
Share bugs, ideas, or general feedback.
Go's design rewards simplicity, composition, explicit error handling, and small interfaces. This skill steers Claude toward code that satisfies the major community style guides — Effective Go, Google's Go Style, Uber's Go Style, and the Go Code Review Comments — while incorporating modern stdlib idioms (errors.Is/As wrapping, context.Context, log/slog, generics, fuzz tests).
Covers: error wrapping (errors.Is/As, %w), context.Context propagation, log/slog structured logging, generics with type parameters and constraints, iter.Seq range-over-func, goroutines / channels / select, defer, embedding, interfaces, struct tags, JSON marshaling, net/http patterns, project layout, internal packages, build tags, table-driven tests, t.Run / t.Cleanup, fuzz testing, go vet, golangci-lint, govulncheck, go workspaces.
These rules cross-cut most Go tasks. Internalize them before reaching for an API-specific reference.
_ to discard an error without a comment justifying why. Wrap with fmt.Errorf("...: %w", err) to add context while preserving the chain; replace (no %w) only when the underlying error is an implementation detail you want to hide.io.Reader over FileLike.go statement must have a clear answer to "how does this stop?" (context cancellation, channel close, sync.WaitGroup). Unbounded go func() is a leak.context.Context as the first parameter to anything that does I/O, blocks, or may be cancelled. Never store it in a struct. Never pass nil — use context.TODO() if you genuinely have nothing.var x T is a valid starting state. sync.Mutex{}, bytes.Buffer{}, and strings.Builder{} are the canonical examples. Don't require a New* constructor when a literal works.sync.Mutex for guarded shared state, sync/atomic for counters and flags. Always run go test -race in CI.gofmt is non-negotiable — never argue with it, never reformat by hand. goimports for import grouping. CI must fail on unformatted code.users not user_utils, httputil not HTTPUtil. Importers will type the name often; respect their fingers.| Scenario | Use | Why |
|---|---|---|
| Allocating a slice, map, or channel | make | Initializes the internal structure; new returns a zeroed pointer that's unusable for these |
| Allocating a struct you need a pointer to | &T{...} | Lets you initialize fields; new(T) only gives the zero value |
| Method mutates receiver, or receiver > ~64 bytes | Pointer receiver | Avoids copy; required for mutation visibility |
Small immutable type (time.Time-style) | Value receiver | Cheap copy, no aliasing surprises, safe in maps |
| Function returns a domain type | Concrete type | Caller can assert to the interfaces they need; preserves API evolution |
| Function parameter describes behavior | Interface (smallest possible) | Decouples caller; testability without mocks |
| Adding context to a returned error | fmt.Errorf("...: %w", err) | Preserves errors.Is/As chain |
| Hiding the underlying error (it's an implementation detail) | New sentinel/typed error, no %w | Don't leak internal abstractions |
| Coordinating goroutines on a result | Channel | Ownership transfer; composes with select and context |
| Protecting mutable shared state | sync.Mutex | Lower overhead than channels for guarded fields |
| Cancellation/deadline across boundaries | context.Context + select { case <-ctx.Done(): } | Standard contract throughout stdlib |
| Same algorithm over multiple types | Generic function with a constraint | Type safety without interface{} + reflection |
| Logging an error with structured fields | slog.Error("msg", "err", err, "key", v) | Structured, leveled, context-aware |
| Optional configuration for a constructor | Functional options (func(*T)) | Backwards-compatible API growth |
| Iterating a custom sequence (Go 1.23+) | iter.Seq / iter.Seq2 + range | First-class push iterators; composes with stdlib |
Example 1: User says "this error message just says EOF, I can't tell where it came from"
Actions:
return errreturn fmt.Errorf("read config from %s: %w", path, err)errors.Is(err, io.EOF) still work because of %w
Result: Error chain carries operational context without breaking sentinel checks.Example 2: User says "my goroutine is leaking — pprof shows them piling up" Actions:
go func() and trace its exit conditionctx context.Context plumbing if missing; replace blocking sends/receives with select { case ...: case <-ctx.Done(): return }cancel() (defer it) so children unwind
Result: Each goroutine has a deterministic lifetime tied to a context.Example 3: User says "I want to add validation to my User struct, what's idiomatic?" Actions:
NewUser constructor — keep the zero value usable if possible(u User) Validate() error method returning a typed error so callers can errors.AsUserOption func(*User))
Result: Consumers can use User{} literals; complex configurations remain extensible.| Symptom | Reference |
|---|---|
gofmt keeps reformatting your code; doc comments missing on exported names | formatting-and-comments.md |
| Linter flags name (Get prefix, stutter, ALL_CAPS, package name underscore) | naming.md |
defer running in unexpected order; for loop variable captured wrong | control-flow.md |
| Mixed value/pointer receivers; named returns hiding bugs; variadic edge cases | functions-and-methods.md |
append "shared backing array" surprise; nil vs empty slice; map iteration order | slices-maps-strings.md |
new vs &T{} confusion; struct tag syntax errors; zero value not usable | structs-and-composites.md |
| Interface defined in wrong package; type assertion panics; embedding leaking methods | interfaces-and-embedding.md |
errors.Is returns false; bare return err; panic that should be an error | errors.md |
Data race detected; goroutine leak; channel deadlock; context.Context misuse | concurrency.md |
Generic function won't compile; comparable constraint surprise; reflection overuse | generics.md |
Test ordering bugs with t.Parallel; missing t.Helper; flaky benchmarks | testing.md |
go.mod confusion; v2+ import path; replace for local dev; vulnerability check | modules-and-tooling.md |
Cyclic imports; util/common packages; where does internal/ go | project-layout.md |
HTTP client missing timeout; response body not closed; JSON tag wrong; math/rand for security | stdlib-patterns.md |
log.Printf in library code; logging in a hot path; structured fields missing | logging-and-observability.md |
gofmt/goimports invariants, godoc-style doc comments, package commentsif/for/switch/type switch, range, range-over-func/iter.Seq, defer, early-returnmake/append/copy, capacity gotchas, nil-vs-empty, map iteration, strings.Buildernew vs &T{}, useful zero values%w wrapping, errors.Is/As/Unwrap, custom types, panic/recoverselect, context.Context, sync primitives, race detector, channel-vs-mutexcomparable, constraints.Ordered, custom unions), when to use genericst.Run/t.Helper/t.Cleanup/t.Parallel, golden files, fuzz, benchmarks, examplesgo.mod/go.sum, SemVer + import versioning, go vet, golangci-lint, govulncheck, workspacesinternal/, cmd/, anti-patterns, layeringnet/http (server + client), encoding/json, io.Reader/Writer, crypto/rand, database/sqllog/slog, structured/leveled logging, attribute conventions, when to log vs return