Skillshub go-code-review
Use when reviewing Go code or checking code against community style standards. Also use proactively before submitting a Go PR or when reviewing any Go code changes, even if the user doesn't explicitly request a style review. Does not cover language-specific syntax — delegates to specialized skills.
git clone https://github.com/ComeOnOliver/skillshub
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/cxuu/golang-skills/go-code-review" ~/.claude/skills/comeonoliver-skillshub-go-code-review && rm -rf "$T"
skills/cxuu/golang-skills/go-code-review/SKILL.mdGo Code Review Checklist
Review Procedure
Use
when formatting the output of a code review to ensure consistent structure with Must Fix / Should Fix / Nits severity grouping.assets/review-template.md
- Run
andgofmt -d .
to catch mechanical issues firstgo vet ./... - Read the diff file-by-file; for each file, check the categories below in order
- Flag issues with specific line references and the rule name
- After reviewing all files, re-read flagged items to verify they're genuine issues
- Summarize findings grouped by severity (must-fix, should-fix, nit)
Validation: After completing the review, re-read the diff once more to verify every flagged issue is real. Remove any finding you cannot justify with a specific line reference.
Formatting
- gofmt: Code is formatted with
orgofmt
→ go-lintinggoimports
Documentation
- Comment sentences: Comments are full sentences starting with the name being described, ending with a period → go-documentation
- Doc comments: All exported names have doc comments; non-trivial unexported declarations too → go-documentation
- Package comments: Package comment appears adjacent to package clause with no blank line → go-documentation
- Named result parameters: Only used when they clarify meaning (e.g., multiple same-type returns), not just to enable naked returns → go-documentation
Error Handling
- Handle errors: No discarded errors with
; handle, return, or (exceptionally) panic → go-error-handling_ - Error strings: Lowercase, no punctuation (unless starting with proper noun/acronym) → go-error-handling
- In-band errors: No magic values (-1, "", nil); use multiple returns with error or ok bool → go-error-handling
- Indent error flow: Handle errors first and return; keep normal path at minimal indentation → go-error-handling
Naming
- MixedCaps: Use
orMixedCaps
, never underscores; unexported ismixedCaps
notmaxLength
→ go-namingMAX_LENGTH - Initialisms: Keep consistent case:
/URL
,url
/ID
,id
/HTTP
(e.g.,http
,ServeHTTP
) → go-namingxmlHTTPRequest - Variable names: Short names for limited scope (
,i
,r
); longer names for wider scope → go-namingc - Receiver names: One or two letter abbreviation of type (
forc
); noClient
,this
,self
; consistent across methods → go-namingme - Package names: No stuttering (use
notchubby.File
); avoidchubby.ChubbyFile
,util
,common
→ go-packagesmisc - Avoid built-in names: Don't shadow
,error
,string
,len
,cap
,append
,copy
,new
→ go-declarationsmake
Concurrency
- Goroutine lifetimes: Clear when/whether goroutines exit; document if not obvious → go-concurrency
- Synchronous functions: Prefer sync over async; let callers add concurrency if needed → go-concurrency
- Contexts: First parameter; not in structs; no custom Context types; pass even if you think you don't need to → go-context
Interfaces
- Interface location: Define in consumer package, not implementor; return concrete types from producers → go-interfaces
- No premature interfaces: Don't define before used; don't define "for mocking" on implementor side → go-interfaces
- Receiver type: Use pointer if mutating, has sync fields, or is large; value for small immutable types; don't mix → go-interfaces
Data Structures
- Empty slices: Prefer
(nil) overvar t []string
(non-nil zero-length) → go-data-structurest := []string{} - Copying: Be careful copying structs with pointer/slice fields; don't copy
methods' receivers by value → go-data-structures*T
Security
- Crypto rand: Use
for keys, notcrypto/rand
→ go-defensivemath/rand - Don't panic: Use error returns for normal error handling; panic only for truly exceptional cases → go-defensive
Declarations and Initialization
- Group similar: Related
/var
/const
in parenthesized blocks; separate unrelated → go-declarationstype - var vs :=: Use
for intentional zero values;var
for explicit assignments → go-declarations:= - Reduce scope: Move declarations close to usage; use if-init to limit variable scope → go-declarations
- Struct init: Always use field names; omit zero fields;
for zero structs → go-declarationsvar - Use
: Preferany
overany
in new code → go-declarationsinterface{}
Functions
- File ordering: Types → constructors → exported methods → unexported → utilities → go-functions
- Signature formatting: All args on own lines with trailing comma when wrapping → go-functions
- Naked parameters: Add
comments for ambiguous bool/int args, or use custom types → go-functions/* name */ - Printf naming: Functions accepting format strings end in
forf
→ go-functionsgo vet
Style
- Line length: No rigid limit, but avoid uncomfortably long lines; break by semantics, not arbitrary length → go-style-core
- Naked returns: Only in short functions; explicit returns in medium/large functions → go-style-core
- Pass values: Don't use pointers just to save bytes; pass
notstring
for small fixed-size types → go-performance*string - String concatenation:
for simple;+
for formatting;fmt.Sprintf
for loops → go-performancestrings.Builder
Logging
- Use slog: New code uses
, notlog/slog
orlog
for operational logging → go-loggingfmt.Println - Structured fields: Log messages use static strings with key-value attributes, not fmt.Sprintf → go-logging
- Appropriate levels: Debug for developer tracing, Info for notable events, Warn for recoverable issues, Error for failures → go-logging
- No secrets in logs: PII, credentials, and tokens are never logged → go-logging
Imports
- Import groups: Standard library first, then blank line, then external packages → go-packages
- Import renaming: Avoid unless collision; rename local/project-specific import on collision → go-packages
- Import blank:
only in main package or tests → go-packagesimport _ "pkg" - Import dot: Only for circular dependency workarounds in tests → go-packages
Generics
- When to use: Only when multiple types share identical logic and interfaces don't suffice → go-generics
- Type aliases: Use definitions for new types; aliases only for package migration → go-generics
Testing
- Examples: Include runnable
functions or tests demonstrating usage → go-documentationExample - Useful test failures: Messages include what was wrong, inputs, got, and want; order is
→ go-testinggot != want - TestMain: Use only when all tests need common setup with teardown; prefer scoped helpers first → go-testing
- Real transports: Prefer
+ real client over mocking HTTP → go-testinghttptest.NewServer
Automated Checks
Run automated pre-review checks:
bash scripts/pre-review.sh ./... # text output bash scripts/pre-review.sh --json ./... # structured JSON output
Or manually:
gofmt -l <path> && go vet ./... && golangci-lint run ./...
Fix any issues before proceeding to the checklist above. For linter setup and configuration, see go-linting.
Integrative Example
Read references/WEB-SERVER.md when building a production HTTP server and want to verify your code applies concurrency, error handling, context, documentation, and naming conventions together.
Related Skills
- Style foundations: See go-style-core when resolving formatting debates or applying the clarity > simplicity > concision priority
- Linting setup: See go-linting when configuring golangci-lint or adding automated checks to CI
- Error strategy: See go-error-handling when reviewing error wrapping, sentinel errors, or the handle-once pattern
- Naming conventions: See go-naming when evaluating identifier names, receiver names, or package-symbol stuttering
- Testing patterns: See go-testing when reviewing test code for table-driven structure, failure messages, or helper usage
- Concurrency safety: See go-concurrency when reviewing goroutine lifetimes, channel usage, or mutex placement
- Logging practices: See go-logging when reviewing log usage, structured logging, or slog configuration