Linters, formatters and type checkers: Checking code automatically
In short: Three kinds of tools that check code automatically: linters find errors and poor style, formatters unify the appearance, type checkers find type errors before running.
In more detail: Many errors can be found without running the program. Static analysis reads the code and sounds an alarm for anything suspicious. The tools run in the editor, before the commit and in the pipeline and save discussions about trivia in code reviews.
In Depth
Linter
A linter checks for likely errors and rule violations: unused variables, missing await, unreachable code, possible null accesses, unsafe functions. Examples: ESLint (JavaScript/TypeScript), Pylint, Ruff and Flake8 (Python), Clippy (Rust), golangci-lint (Go), ShellCheck (shell), Stylelint (CSS). Rules can be configured per project.
Formatter
A formatter rewrites the code according to a fixed scheme: indentation, line length, quotes, brackets. This ends arguments about style, and changes in the history show only real differences. Examples: Prettier (web), Black and Ruff format (Python), gofmt (Go), rustfmt, clang-format. The principle: few options, one standard.
Type checker
A type checker compares type annotations with usage, e.g. “this function expects a number but gets text”. In TypeScript it is the compiler (tsc); in Python there are mypy, Pyright and Pyre for type annotations. It finds many errors that would otherwise only appear at runtime and serves as living documentation.
Use
- In the editor (language server) instant feedback.
- As a pre-commit hook (Husky, pre-commit): only clean code is checked in.
- In the CI pipeline: violations make the build fail.
- Take warnings seriously but set rules pragmatically: too many rules lead to them being ignored or switched off by comment. Besides these tools, tests and code reviews complement quality assurance.
See also: Clean code, Code review, Type systems, CI/CD pipeline