go-clean-architecture
Use when scaffolding or refactoring a Go service into a framework-agnostic clean (hexagonal) architecture: Domain, Usecase,…
Use when designing, propagating, or debugging context.Context flow in Go — first-parameter placement, deadlines and cancellation, request-scoped values, WithoutCancel for fire-and-forget work, and key-collision-safe value patterns. Apply proactively whenever a function takes
Claude Code
$ npx -y skills add muratmirgun/gophers --skill go-context --agent claude-code
Codex
$ npx skills add muratmirgun/gophers --skill go-context -a codex -y
Cursor
$ npx skills add muratmirgun/gophers --skill go-context -a cursor -y
Gemini CLI
$ npx skills add muratmirgun/gophers --skill go-context -a gemini-cli -y
GitHub Copilot
$ npx skills add muratmirgun/gophers --skill go-context -a github-copilot -y
OpenCode
$ npx skills add muratmirgun/gophers --skill go-context -a opencode -y
Windsurf
$ npx skills add muratmirgun/gophers --skill go-context -a windsurf -y
name: go-context description: "Use when designing, propagating, or debugging context.Context flow in Go — first-parameter placement, deadlines and cancellation, request-scoped values, WithoutCancel for fire-and-forget work, and key-collision-safe value patterns. Apply proactively whenever a function takes ctx, spawns work, or accepts request-scoped data, even if the user has not asked about context." license: MIT compatibility: "Designed for Claude Code or similar AI coding agents. Requires Go 1.7+ (context in std lib). context.WithoutCancel needs Go 1.21+." allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*)
`context.Context` carries the cancellation, deadline, and request-scoped values for a single unit of work. Pass it explicitly through the entire call chain — never store it, never replace it with `Background()` mid-flight, never use it as a side-channel for ordinary parameters.
1. **`ctx` is the first parameter**, named `ctx context.Context`. No exceptions outside interface stubs imposed by external APIs. 2. **Propagate the caller's `ctx`** all the way down. Do not start a new tree with `context.Background()` inside a request path. 3. **Do not store `Context` in a struct**. Pass it to each method that needs it. 4. **Always `defer cancel()`** after `WithCancel`/`WithTimeout`/`WithDeadline`, unless ownership is explicitly transferred. 5. **Context values are for request-scoped metadata only** (request ID, auth principal, trace). Never for optional function parameters or config. 6. **Value keys must be unexported named types** to prevent cross-package collisions.
Pick the most explicit option that fits — context values are the last resort.
| Option | Use for | Why | |---|---|---| | Function parameter | Anything the function *needs* to do its job | Type-checked, visible at call site | | Method receiver | State that belongs to the type | Already in scope | | Package-level config | Process-wide, immutable | One owner, no hidden flow | | `context.Value` | Request-scoped metadata that crosses layers without being a function arg | Untyped — use sparingly |
> Read [references/values-and-keys.md](references/values-and-keys.md) for the unexported-key pattern, typed accessors, and OpenTelemetry/trace propagation.
| Situation | Use | |---|---| | `main`, `init`, top-level test | `context.Background()` | | Placeholder while plumbing is incomplete | `context.TODO()` | | Inside an HTTP handler | `r.Context()` | | Need manual cancellation | `context.WithCancel(parent)` | | Need a deadline / timeout | `context.WithTimeout(parent, d)` / `WithDeadline` | | Background work that must outlive the request (Go 1.21+) | `context.WithoutCancel(parent)` |
// Bad — breaks the chain, downstream cannot be cancelled
func (s *OrderService) Create(ctx context.Context, o Order) error {
return s.db.ExecContext(context.Background(), insertSQL, o.ID)
}
// Good — same ctx flows HTTP handler -> service -> DB -> external API
func (s *OrderService) Create(ctx context.Context, o Order) error {
return s.db.ExecContext(ctx, insertSQL, o.ID)
}ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel() // release resources even on the happy path
select {
case <-ctx.Done():
return ctx.Err()
case res := <-doAsync(ctx):
return res
}> Read [references/cancellation-and-deadlines.md](references/cancellation-and-deadlines.md) for `WithoutCancel`, `AfterFunc`, and long-running goroutine cancellation patterns.
// Bad — pollutes the standard signature
type MyCtx interface {
context.Context
UserID() string
}
// Good — keep the signature standard, extract via helper
func UserIDFrom(ctx context.Context) (string, bool) { /* ... */ }Most context mistakes are mechanical and a linter will catch them in CI before review:
Run `golangci-lint run --enable=contextcheck,noctx,staticcheck` in CI for any project that exposes `context.Context`.
| Anti-pattern | Why it hurts | Do this instead | |---|---|---| | `ctx context.Context` stored on a struct field | Lifetime becomes invisible; outlives the request | Pass `ctx` to each method | | `context.Background()` mid-call | Cancellation chain breaks; goroutines leak | Use the caller's `ctx` | | `ctx.Value("user-id")` with a string key | Cross-package collisions, no type safety | Unexported key type + typed getter | | Passing `nil` as a context | Panics on `Done()` / `Value()` | Use `context.TODO()` while plumbing | | `WithTimeout` without `defer cancel()` | Leaks the timer until parent finishes | `defer cancel()` on the next line | | Custom `MyContext` interface | Breaks every standard signature | Keep `context.Context`, extract with helpers |
26 production-grade Go skills for Claude Code, Gemini CLI, and opencode. Battle-tested patterns from the Go community — codified as triggerable AI skills.
Use when scaffolding or refactoring a Go service into a framework-agnostic clean (hexagonal) architecture: Domain, Usecase,…
Invoke this skill to systematically review a Go change against community style standards before merging. Walks the diff topic by…
Use when writing or reviewing Go code for clarity, formatting, control flow, variable declarations, switch usage, and function…
Use when writing or reviewing concurrent Go code — goroutines, channels, select, mutexes, atomics, errgroup, singleflight, worker…
Use when writing conditionals, loops, switches, type switches, or blank-identifier patterns in Go. Covers if-with-initialization,…
Use when choosing or operating on Go slices, maps, arrays, strings, or container/* types — including slice internals, capacity…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.