Overview
go vet ships only high-confidence checks; the community fills the gap. staticcheck is
the reference third-party analyser — near-zero false positives, treated by many teams as
mandatory as vet — and golangci-lint is the meta-runner that executes it alongside dozens
of other linters from one config, one cached pass, one CI step.
Key points
- staticcheck categories:
SA(bugs: misuse of APIs, impossible conditions, concurrency mistakes),S(simplifications),ST(style),QF(quick fixes). SA is the non-negotiable core;SA1019flags use ofDeprecated:APIs. - golangci-lint: runs many linters in one process over a shared AST/SSA load;
configured via
.golangci.yml(enable/disable, per-path excludes, severity); the standard PR gate in Go CI. - Enabled-set discipline: enable a small, named list you can defend — typically
staticcheck,govet,errcheck,unused+ a handful — rather than "enable-all", which churns on every release and buries signal in style noise. - errcheck: finds silently dropped error returns — Go's most consequential lint, since the compiler only rejects unused variables, not unused results.
- revive: the configurable style linter (successor to golint) — naming, comments on exported identifiers, per-rule severity.
- gosec: security-pattern scanning (hardcoded credentials, weak crypto, command injection) — noisier, worth scoping to the checks you'll act on.
- False-positive management: prefer narrow inline suppression
(
//nolint:errcheck // close on read-only file) with a required reason, over global excludes; review nolint growth in code review. - New-code-only adoption: on legacy codebases, gate only newly changed lines
(
--new-from-rev) instead of demanding a big-bang cleanup.
Examples
# .golangci.yml — small and intentional
linters:
disable-all: true
enable: [govet, staticcheck, errcheck, unused, ineffassign, gosec]
linters-settings:
errcheck: { check-type-assertions: true }
Related
- The go command & tool catalog — parent catalog of the toolchain.
- go vet — the first-party baseline these tools extend.
- gopls — surfaces a staticcheck subset live in the editor, before CI sees it.
- govulncheck — sibling analyser aimed at known vulnerabilities rather than code quality.
- Code review — lint automates the mechanical findings so review can argue about design.