Static Analysis & Linting Roadmap¶
"The cheapest bug to fix is the one your editor underlines before you ever hit save."
This roadmap is about tools that read your source code without running it — linters, formatters, type-checkers, security scanners, and data-flow engines that find bugs, enforce style, surface dead code, and trace tainted input at the speed of a keystroke rather than a test run. It covers what each class of tool can and cannot prove, where false positives come from, how to write your own rules, and how to wire all of it into the development loop without drowning the team in noise.
Looking for type-system theory (variance, inference, ADTs, effect systems)? See Type Systems.
Looking for security review (threat modelling, auth, crypto, hardening)? See the Security section.
Looking for clean code style rules at the source level (naming, function shape, comments)? See Clean Code.
Looking for runtime analysis (sanitizers, fuzzing, Valgrind)? See Dynamic Analysis & Sanitizers.
Why a Dedicated Roadmap¶
Every team adopts a linter, then argues for years about which rules to enable. Understanding static analysis as a category — what each class of tool can and cannot prove, where false positives come from, and how to evolve a rule set without breaking the team — turns linting from a religious war into a load-bearing part of the development loop.
| Roadmap | Question it answers |
|---|---|
| Testing | Does my code work when I run it? |
| Code Review | Does another human understand and trust my code? |
| Static Analysis (this) | What can I prove about my code without running it? |
Sections¶
| # | Topic | Focus |
|---|---|---|
| 01 | Linters & Style Checkers | What a linter proves vs what it enforces; rule classes, severity, the false-positive budget; ESLint, golangci-lint, Pylint/Ruff, Clippy, Checkstyle |
| 02 | Formatters | Deterministic rewriting vs lint; gofmt/Prettier/Black/rustfmt; format-on-save, the "no config" philosophy, ending style debates |
| 03 | Type Checkers & Gradual Typing | mypy/pyright, TypeScript, Flow; soundness vs ergonomics, any as escape hatch, strictness ratchets, type checking as the cheapest analysis |
| 04 | SAST & Security Scanners | Semgrep, CodeQL, Bandit, gosec; sources/sinks, rule packs, signal-to-noise, where SAST fits in the SDLC |
| 05 | Dead Code & Complexity | Unused code/imports, cyclomatic & cognitive complexity, reachability; the reflective-code false-positive problem |
| 06 | Dependency & License Scanning | SCA, CVE matching (OSV/Trivy/Dependabot/Snyk), license compliance, transitive risk; SBOM-adjacent analysis |
| 07 | Custom Lint Rules & AST | ASTs and matchers; writing Semgrep rules, ESLint plugins, golangci-lint custom linters; codemods and autofix |
| 08 | Taint & Data-Flow Analysis | How interprocedural data-flow works; sources, sinks, sanitizers, propagation; CodeQL queries; the theory under SAST |
| 09 | Static Analysis in CI | Editor → pre-commit → CI placement; baselines for legacy code, blocking vs advisory gates, SARIF, suppression discipline |
Tiers¶
Every topic is written across five tiers, each a standalone page:
| Tier | File | For the reader who… |
|---|---|---|
| Junior | junior.md | is meeting the tool for the first time and needs the what, why, and the commands to run it |
| Middle | middle.md | can run the tools and needs the working policy, the trade-offs, and the false-positive failure modes |
| Senior | senior.md | owns the rule set and must reason about it under constraints, at scale, and across teams |
| Professional | professional.md | sets org-wide standards, builds the platform, and weighs signal, cost, and adoption |
| Interview | interview.md | is preparing to be questioned on it — a question bank with model answers and what each probes |
Languages¶
The roadmap is tool-centric, but examples cover Go (golangci-lint, staticcheck, gofmt), Java (Checkstyle, SpotBugs, Error Prone, PMD), Python (Pylint, Ruff, mypy, Bandit, Black), Rust (Clippy, rustfmt), and JS/TS (ESLint, Prettier, TypeScript, Biome). Different ecosystems make different choices about where to draw the line between "compiler" and "linter," and seeing several side-by-side is the fastest way to understand the design space.
References¶
- Software Engineering at Google — Winters, Manshreck, Wright (the static-analysis chapter on Tricorder and the philosophy of "fix it, don't just report it")
- The Practice of Programming — Brian Kernighan & Rob Pike (the original case for spending tooling effort on the developer's inner loop)
- Semgrep and CodeQL documentation — the two reference points for modern pattern-based and data-flow-based static analysis
- Compilers: Principles, Techniques, and Tools — Aho, Lam, Sethi, Ullman (the data-flow analysis foundations under taint tracking)
- Coders at Work — Peter Seibel (multiple interviewees on the role of warnings, tools, and discipline)
Project Context¶
Part of the Senior Project — a personal effort to consolidate the essential knowledge of software engineering in one place.