Go Analysis Framework: modular static analysis in golang.org/x/tools/go/analysis
Go Analysis Framework: modular static analysis in golang.org/x/tools/go/analysis
Overview
The Go Analysis Framework defines a clean interface between a modular static analysis and the driver program that runs it.
Analyzer
An Analyzer struct fully describes a static analysis: its name, documentation, flags, dependencies, result type, and the Run function that executes the logic on a single package.
Pass
A Pass value supplies the analyzer with the syntax trees, type information, and file set of the package being inspected, plus helpers for reporting diagnostics and accessing results from required analyzers.
Modular analysis with Facts
Facts let an analysis export lightweight, serializable information about objects or packages; the driver propagates these facts to importing packages, enabling cross‑package checks such as detecting printf wrappers without re‑analyzing dependencies.
Testing an Analyzer
The analysistest subpackage provides a harness that runs an analyzer on testdata files and verifies diagnostics and facts using // want comments, making unit tests concise and reliable.
Standalone commands
The singlechecker and multichecker subpackages supply ready‑made main functions so developers can expose a single analyzer or a suite of analyzers as command‑line tools with minimal boilerplate.
Community Reception
Commenters highlight that the framework is already widely adopted and praise its integration with Go’s tooling ecosystem.
"For SpiceDB, we've found a lot of success using this framework to define our own analyzers; it's probably 10x easier now with LLMs. No need for tribal knowledge or more time wasted on code review if you can just turn it into a linter and move on." — @jzelinskie
"You guys can keep complaining about how go is too verbose, but I love everything about go. I love the error handling, I love the forced formatting, i love all the linting it has including style guides. When you read other source code it's so easy to understand it and make sense of it. Thank you go team (Ok, maybe I am a bit sceptical with the latest generic additions, but overall it's a great language. I love it.)" — @b7e7d855b448
"This isn't new? You can see it's used by a lot of linters already: https://pkg.go.dev/golang.org/x/tools/go/analysis?tab=import..." — @jamescun
"Can these sorts of primitives be used to create broader "architectural" linters?" — @mchav
"So what is context? This isn't new and why the submission ?" — @ksec
"I was just looking for this. Will give it a spin." — @hoppp
"The Go team's emphasis on tooling in the service of software engineering is a boon to human and agentic development alike. Give yourself and your agents great tools. An example from one of my recent projects: https://github.com/verdverm/gmd/blob/main/Makefile (give agents simple "tool calls" instead of needing to divine the correct args/flags every time, essentially invocable agents.md content) One of the interesting things to call out from this is using build tags for testing { unit, coverage, recorded, real api }, with the buffet allowing the agent to iterate faster and more targeted. I tend to run the linting and coverage in a new session, have a report generated, and then another fresh session to start dealing with gaps. Another super cool testing tool in the Go internal source is
testscript. Roger Peppe extracted a number of those internal utilities here https://github.com/rogpeppe/go-internal/tree/master/testscri..." — @verdverm
"This is one of the least informative discussions in HN front page that I remember." — @eonwe
"the most valuable thing in this article for me was this: The early loop looked like this: /goal improve the perf by 20% -> a great deal of plausible code -> a confusing benchmark -> another plausible patch Later it looked like this: find the expensive work -> explain why it happens -> change one mechanism -> compare with the previous Rust revision -> test the complete application -> retain, revise, or reject" — @bijowo1676