CLAUDE.md — Go Project
Project Basics
This is a Go project using Go 1.22+. All code must pass go fmt, go vet, and staticcheck. Use the standard library wherever possible before reaching for external dependencies.
Package Structure
cmd/— main applications (one directory per binary)internal/— private packages (not importable by other modules)pkg/— public packages (importable by external consumers, use sparingly)- Keep packages small and focused — one responsibility per package
- Package names are short, lowercase, no underscores:
auth,store,handler
Error Handling
- Always check returned errors — never use
_to discard them - Return errors, don’t panic.
panicis only for truly unrecoverable situations inmain() - Wrap errors with context:
fmt.Errorf("failed to create user: %w", err) - Use
errors.Is()anderrors.As()for error checking, not string comparison - Define sentinel errors at package level:
var ErrNotFound = errors.New("not found") - Custom error types only when callers need to extract structured information
Naming Conventions
MixedCapsfor exported names,mixedCapsfor unexported- Interfaces with single methods use
-ersuffix:Reader,Writer,Stringer - Don’t stutter:
http.Servernothttp.HTTPServer - Acronyms are all caps:
HTTP,URL,ID(notHttp,Url,Id) - Test files:
foo_test.goalongsidefoo.go
Testing
- Table-driven tests for functions with multiple input/output cases
go test ./...must pass before any commit- Use
testing.Tsubtests:t.Run("case name", func(t *testing.T) { ... }) - Test helpers call
t.Helper()first - Use
testify/assertortestify/requireif the project already uses them — don’t mix - Integration tests use build tags:
//go:build integration
Concurrency
- Always pass
context.Contextas the first parameter to long-running functions - Use
sync.WaitGroupfor fan-out, channels for communication - Never start goroutines without a plan for how they stop
- Protect shared state with
sync.Mutex— keep critical sections small - Prefer
selectwithctx.Done()for cancellation
Dependencies
- Run
go mod tidyafter adding or removing imports - Minimize external dependencies — the standard library covers most needs
- Pin major versions in
go.mod - Audit new dependencies before adding: check maintenance, license, and transitive deps
Build & Deploy
- Static binaries:
CGO_ENABLED=0 go build -o bin/app ./cmd/app - Multi-stage Docker builds: build stage with Go image, runtime with
scratchoralpine - Use
-ldflags "-s -w"for smaller release binaries - Cross-compile with
GOOSandGOARCHenvironment variables
Verification
go build ./...— compiles without errorsgo test ./...— all tests passgo vet ./...— no suspicious constructsstaticcheck ./...— no static analysis warnings (if installed)go fmt ./...— properly formatted (should be a no-op)
Git & GitHub
- Do not push code or create PRs without explicit permission
- Do not perform destructive or irreversible git operations without asking first
- Run the full verification suite before committing