# Lang Go

> 10x Go

- Skill: `arhuman/lang-go` (Agent Skill, multi-file: 12 files)
- Install (CLI): `npx skillmds@latest add arhuman/lang-go`
- Raw SKILL.md: https://api.skillmd.com/api/skills/arhuman/lang-go/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: arhuman (https://skillmd.com/u/arhuman)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/arhuman/lang-go

---


# 10x Go

This skill defines rules to write robust, maintainable, and idiomatic production Go code.

## Reference Guide

Load the relevant reference when the task involves:

| Topic | File | Load When |
|-------|------|-----------|
| Concurrency | `references/concurrency.md` | goroutines, channels, context, sync primitives, worker pools |
| Generics | `references/generics.md` | type parameters, constraints, generic data structures |
| Interface Design | `references/interfaces.md` | interface composition, functional options, io patterns, DI |
| Testing | `references/testing.md` | tests, benchmarks, fuzzing, mocking, coverage |
| Project Structure | `references/project-structure.md` | module layout, go.mod, Makefile, Dockerfile, monorepo |
| Error Handling | `references/errors.md` | sentinel errors, wrapping, custom types, GORM context |
| API Projects | `references/api.md` | gin, GORM, JWT, swagger, CORS |
| OpenAPI / Swagger | `references/openapi.md` | swaggo annotations, spec generation, Swagger UI, security schemes |
| CLI Projects | `references/cli.md` | cobra, CLI directory layout |
| REST Patterns | `references/rest-patterns.md` | URI patterns, HTTP status code, naming conventions |
| Memory & Resources | `references/memory.md` | request/response body lifecycle, goroutine limits, heap escape, sync.Pool |

## Architecture Principles

- Favor simplicity. Do not over-engineer the design.
- Depend on interfaces, not concrete types (DI). Prefer small, single-method interfaces (ISP). Each function/type has one responsibility (SRP).
- Favor generic functions over specific ones (`hasRole(string)` instead of `hasAdminRole()` and `hasWriterRole()`).
- ALWAYS make small, atomic, incremental changes rather than big-bang rewrites.
- Introduce interfaces when needed to enable loose coupling.

## MUST DO

- Run `gofmt` and `golangci-lint` on all generated code
- Run `go vet ./...` on all generated code (catches common correctness issues gofmt misses)
- Pass `context.Context` as the first argument to all blocking or I/O-bound functions
- Handle all errors explicitly — no naked `_` discards without justification
- Wrap errors with `fmt.Errorf("operationName: %w", err)` — see `references/errors.md`
- Write table-driven tests with `t.Run` subtests for all non-trivial functions
- Document all exported functions, types, and constants with a docstring
- Run tests with `-race` flag: `go test -race ./...`
- Always apply `http.MaxBytesReader`, drain, and close `r.Body` in HTTP handlers
- Always limit, drain, and close `resp.Body` in HTTP clients — use `io.LimitedReader{R: resp.Body, N: limit+1}` and check `limited.N == 0` to detect (and error on) overflow; never use bare `io.ReadAll(resp.Body)`
- Always close `resp.Body` on `client.Do()` error: if `resp != nil { resp.Body.Close() }` before returning
- Compile regular expressions once at package level (`var re = regexp.MustCompile(...)`) — never inside functions called per request
- Cap goroutine counts with `errgroup.SetLimit` or `semaphore.NewWeighted` — never spawn unbounded goroutines over user-supplied input
- Pre-allocate slices and maps when final size is known: `make([]T, 0, n)`
- Use `errors.Is()` and `errors.As()` for error inspection
- Use `any` instead of `interface{}`
- Use type switches instead of repeated type assertions

## MUST NOT DO

- Use `panic` for recoverable errors
- Use `http.Get`, `http.Post`, or `http.DefaultClient` in production code — always create a dedicated `*http.Client` with an explicit `Timeout`
- Use `io.LimitReader` when you need truncation detection — use `io.LimitedReader{N: limit+1}` and check `N==0` instead; `io.LimitReader` silently truncates
- Create goroutines without a clear termination strategy (WaitGroup, errgroup, or channel signaling)
- Ignore context cancellation in long-running operations
- Hardcode configuration values — use environment variables or functional options
- Use reflection without measurable performance justification
- Return errors without wrapping context (`return err` alone loses the call site)
- Log AND return the same error at the same level — choose one
- Box value types into `any`/`interface{}` on hot paths without profiling justification
- Use `fmt.Sprintf` for string building in loops — use `strings.Builder` instead
- Store pointers to pooled objects outside the `sync.Pool` scope

## Coding Style

- Use PascalCase for exported types/methods, camelCase for variables
- Group imports: standard library, then third-party, then project-specific
- Package names and all exported entities must have docstrings
- Code must be self-documenting with clear, consistent naming
- Avoid nested logic — follow the "happy path" principle

## Quality Standards

- Minimum Go version: 1.22+
- Functions must be small, focused, and easily testable.
- Dependencies must be minimal and well-justified.
- Performance optimizations must be measured, not assumed. Profile with pprof before optimizing.
- Log at Debug level by default; log at Info level for one-time or important events (initialization, configuration).
- Never log secrets, tokens, or PII — scrub before logging.
- Use parameterized GORM queries; never concatenate user input into raw SQL.
- Run `govulncheck ./...` in CI to detect known vulnerabilities in dependencies.

## Module Preferences

- `go.uber.org/zap` for structured logging
- `github.com/stretchr/testify` and its submodules (`require`, `assert`, `suite`) for testing

## Tests

Tests are contracts with the user. See `references/testing.md` for full guidance. Key rules are in **MUST DO** above.

## Agent Behavior

- Reduce redundancy — use tree-sitter (if available) to identify similar code patterns before generating new code.
- Use tree-sitter (if available) to analyze function complexity before refactoring.
- **Preserve test intent**: you may refactor test structure and helpers freely, but you MUST ASK for confirmation before changing test assertions, removing test cases, or altering expected behavior.
- When adding new test cases: add with a `// TODO: uncomment and validate` comment and notify the user.

