Introduction
Staticcheck is a static analysis tool for Go that goes beyond what the standard go vet provides. It detects real bugs, highlights deprecated API usage, identifies performance anti-patterns, and suggests idiomatic simplifications, making it one of the most trusted quality tools in the Go ecosystem.
What Staticcheck Does
- Detects bugs like unused results, incorrect format strings, and infinite loops
- Flags deprecated standard library functions with their recommended replacements
- Identifies performance issues such as unnecessary allocations and redundant conversions
- Suggests code simplifications (e.g., replacing loops with
append, removing dead branches) - Checks for common concurrency mistakes with goroutines and channels
Architecture Overview
Staticcheck loads Go packages using the go/packages API, builds SSA (Static Single Assignment) form via golang.org/x/tools/go/ssa, and runs a suite of analyzers over the SSA representation. Each analyzer is an independent check with its own diagnostic ID (SA, S, ST, QF, U prefixes). Results are emitted in text, JSON, or SARIF format for integration with CI systems and code review tools.
Self-Hosting & Configuration
- Install with
go install honnef.co/go/tools/cmd/staticcheck@latest - Run
staticcheck ./...in any Go module to analyze all packages - Configure checks via a
staticcheck.conffile or inline//lint:ignoredirectives - Disable specific checks by ID (e.g.,
-checks=-ST1000) for project-specific style - Integrates with golangci-lint as a bundled analyzer
Key Features
- Over 150 checks spanning correctness, performance, style, and simplification
- SSA-based analysis catches issues that AST-level linters miss
- SARIF output for GitHub Code Scanning and CI integration
- Quickfix suggestions that editors can apply automatically
- Stable check IDs make it safe to pin and track across versions
Comparison with Similar Tools
- go vet — ships with Go but covers fewer checks; Staticcheck adds 100+ additional analyses
- golangci-lint — meta-linter that bundles Staticcheck alongside other linters
- Revive — rule-based linter focused on style; Staticcheck emphasizes correctness and bugs
- gopls — Go language server that surfaces some Staticcheck diagnostics in editors
- errcheck — single-purpose (unchecked errors); Staticcheck covers errors plus much more
FAQ
Q: How does Staticcheck differ from go vet? A: go vet ships with the Go toolchain and covers about 30 checks. Staticcheck adds over 150 deeper analyses including deprecation detection, performance hints, and code simplification.
Q: Can I use Staticcheck in CI?
A: Yes. Run staticcheck -f json ./... or -f sarif for machine-readable output compatible with GitHub Actions and other CI systems.
Q: Does it support Go generics? A: Yes, Staticcheck fully supports generic code introduced in Go 1.18.
Q: Can I suppress specific warnings?
A: Use //lint:ignore CHECK_ID reason comments or disable checks globally in staticcheck.conf.