Go code review
Goal: the change should make the codebase healthier. It does not need to be perfect. Do not block a change because of personal taste.
Step 1: Get the change
- If the user gave a diff, PR, or files, use that.
- In a git repo:
git diff --stat main...HEAD, thengit diff main...HEAD(trymasterororigin/mainifmaindoesn't exist). For uncommitted work:git diffandgit diff --staged. - If the purpose of the change is unclear, ask in one short line.
Step 2: Read the context
- Open the whole file around every changed function, not only the diff lines.
- Find callers of changed exported functions:
grep -rn "FuncName(" --include=*.go - Check the Go version in
go.mod. Some advice depends on it (loop variables are per-iteration since Go 1.22).
Step 3: Run the tools (if you can run commands)
go build ./...
go vet ./...
go test -race ./... # only changed packages if the repo is slow
golangci-lint run ./... # only if installed or the repo has a config
Report real failures. For formatting, just say "run gofmt" once; don't list every line. If you cannot run commands, say so in one line.
Step 4: Review in this order
Big things first. If the design is wrong, say that first and skip the nits.
- Design – Does this change belong here (this package, this service)? Does it fit the rest of the system? Is now the right time for it?
- Functionality – Does it do what the author wanted? Is that good for the people who use it (end users and future developers)? Think about edge cases and concurrency.
- Complexity – Can a reader understand it quickly? Watch for over-engineering: code built for an imagined future instead of today's problem.
- Tests – Are there tests in the same change? Would they fail if the code broke? Are they simple?
- Naming – Clear, not too long, Go-style.
- Comments – Explain why, not what. Stale comments and finished TODOs removed.
- Style – gofmt, style guide. Personal preference = Nit only.
- Consistency – Style guide wins over surrounding code. If the guide says nothing, follow the surrounding code.
- Documentation – README, godoc, config/env vars, migrations updated if behavior changed.
- Every line – Read all human-written code. Generated code (
*.pb.go, mocks, sqlc output) can be skimmed. - Code health – Does the whole system get better or worse with this change?
- Good things – Name real good things you see.
For Go-specific checks in each area, read references/go-checklist.md.
Always check its Errors, Concurrency and Resources sections; most Go bugs live there.
Severity labels
- Blocker – bug, data race, goroutine leak, security issue, broken test, wrong design. Must fix before merge.
- Should fix – real problem, not urgent. The author can argue.
- Nit – small optional improvement. Always start the comment with "Nit:".
- Question – something you don't understand. If you can't understand it, others won't either; ask for clearer code.
Do not invent problems. A good change gets a short review. If you are not sure something is a bug, use Question, not Blocker. If asked to review only some files or aspects, say which parts you reviewed.
Output format
## Summary
1–2 sentences: what the change does. Verdict: Approve / Approve with comments / Needs changes.
## Blockers
- `path/file.go:42` – what is wrong and why it matters.
```go
// suggested fix
```
## Should fix
## Nits
## Questions
## Good things
## What I checked
Tools run and results, files reviewed, anything skipped.
Leave out empty sections. Each comment: problem, why, fix. Keep it short.