Documentation & godoc Conventions
Package comments, examples, and internal playbooks.
Go documentation is comments interpreted by go doc and pkg.go.dev.
Teams that treat docs as part of the API reduce onboarding friction, improve review quality, and make generated reference material trustworthy.
Summary
godoc is the default reference surface for Go packages.
Package comments explain purpose and usage patterns.
Symbol comments document behavior, concurrency rules, and error semantics.
Examples provide executable snippets.
Internal playbooks cover runbooks and onboarding steps godoc should not try to hold.
Recipe
Quick-reference recipe card - copy-paste ready.
// Package ratelimit provides token-bucket rate limiting for HTTP handlers.
//
// Use NewLimiter at process startup and share one Limiter across handlers.
// Limiters are safe for concurrent use.
package ratelimit
// Limiter controls request rate using a token bucket.
type Limiter struct { /* ... */ }
// Allow reports whether one event may proceed at time now.
// It is safe for concurrent use by multiple goroutines.
func (l *Limiter) Allow(now time.Time) bool { /* ... */ }When to reach for this:
- Exporting new packages or public HTTP/gRPC APIs
- Onboarding engineers who ask "where is the docs?"
- Reviewing PRs that add exported types without comments
- Preparing a library for external or cross-team consumption
Working Example
A library adds executable documentation and a package overview.
// example_test.go
package ratelimit_test
import (
"fmt"
"time"
"example.com/lib/ratelimit"
)
func ExampleNewLimiter() {
lim := ratelimit.NewLimiter(10, time.Second)
ok := lim.Allow(time.Now())
fmt.Println(ok)
// Output: true
}go test -run Example
go doc example.com/lib/ratelimitWhat this demonstrates:
- Examples live in
*_test.gowithExampleprefix and optional// Output:. go testruns examples as tests; broken examples fail CI.- Package comment orients readers before they read
Limitermethods. - Reviewers block merge if exported symbols lack comments.
Deep Dive
How It Works
- The go/doc tool parses comments immediately above exported declarations.
- Package comments sit before
packageclause (only one file per package should carry the main block). - Sentences should be complete phrases; godoc renders them as reference prose.
- pkg.go.dev shows examples, constants, and deprecated notices from comment text.
Comment Checklist
| Element | Rule |
|---|---|
| Exported func/type/const | Comment starts with name; states what it does |
| Errors | Document return conditions and retryability |
| Context | Note cancellation effects |
| Concurrency | State safe/unsafe explicitly |
| Zero value | Say whether zero value is useful |
| Deprecated | // Deprecated: use NewX instead |
Go Notes
// Bad - comment does not start with symbol name
// Returns a limiter for rate control.
func NewLimiter(rate int, window time.Duration) *Limiter
// Good
// NewLimiter returns a Limiter that allows rate events per window.
func NewLimiter(rate int, window time.Duration) *Limiter// ErrRateExceeded indicates the client exceeded quota.
// Callers may retry after RetryAfter duration.
var ErrRateExceeded = errors.New("rate exceeded")Link related types with plain text names; godoc auto-links identifiers when possible.
Internal Playbooks vs godoc
- godoc: stable API contracts, usage, errors, concurrency.
- Playbooks (wiki/README): deploy steps, on-call, credentials, architecture diagrams.
- Onboarding docs: team-specific ramp (this section's pages).
- Do not paste secrets or environment-specific URLs into godoc comments.
Gotchas
- Comment on wrong line - godoc attaches to next exported symbol only. Fix: comment directly above declaration with no blank line.
- Package comment in every file - pkg.go.dev shows duplicates awkwardly. Fix: one
doc.goor designated file per package. - Examples with network I/O - flaky on pkg.go.dev. Fix: use fakes or
httptest.Serverwith deterministic output. - Documenting unexported helpers - noise for readers. Fix: comment only exports unless internal team package with clear audience.
- Stale comments after behavior change - worse than no comment. Fix: require doc updates in PR template for API changes.
- Using godoc for incident runbooks - operators need searchable wikis with paging links. Fix: cross-link playbook from README, not from symbol comments.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| README only | Internal cmd tools | Exported libraries consumed by other teams |
| OpenAPI for HTTP | REST surface is primary contract | Pure Go libraries with no HTTP |
| Protobuf comments | gRPC is main API | Hand-written Go client helpers still need godoc |
| Generated docs (swaggo) | Large HTTP surface | You still need package-level Go comments for logic |
FAQs
Must every unexported symbol stay undocumented?
Document unexported items when complexity demands it, but godoc will not show them on pkg.go.dev. Prefer clear names for internals.
How long should comments be?
One to three sentences for most symbols. Longer prose belongs in package comment or markdown design docs linked from README.
Do we document tests?
Test names and table cases are documentation for teammates. Use Example functions when you want pkg.go.dev snippets.
How handle deprecated APIs?
Add Deprecated: line with replacement and timeline. Reviewers block new uses of deprecated symbols in application code.
Should package comments mention Go version requirements?
Yes when APIs need generics or new stdlib symbols. Align with module go directive in go.mod.
What about non-English comments?
Match team policy. Mixed languages harm search and onboarding; most production codebases standardize on English for exports.
How verify docs in CI?
Run go test for examples, optionally go vet and linters that check comment sentences on exports.
Who owns playbooks?
Service owners rotate quarterly review of README and runbook links; platform teams own shared templates.
How do docs relate to ADRs?
ADRs record why; godoc records what and how. Link ADRs in README, not in every function comment.
Should AI draft godoc?
Authors must verify accuracy against code paths and errors. Reviewers treat wrong godoc as a blocking bug.
Related
- Team Onboarding Basics -
go docexploration exercise - Code Review Culture for Go - blocking on missing export docs
- Examples as Executable Documentation - Example test details
- Coding Standards & Doc Conventions - org-wide prose rules
- Effective Go Rules Checklist - godoc items in review
Stack versions: This page was written for Go 1.26.x (Green Tea GC default, go fix modernizers - verify patch at build), chi (latest - verify at build), gin (latest - verify at build), echo (latest - verify at build), google.golang.org/grpc (latest - verify at build), sigs.k8s.io/controller-runtime (latest - verify at build), kubebuilder (latest - verify at build), tinygo (latest - verify board targets at build), wazero (latest - verify at build), and golangci-lint (latest - verify linter set at build).