Dev ToolingDev Tooling
What Code Quality Tools Actually Do
Dev Tooling

What Code Quality Tools Actually Do

Lewis SmithArticle by Lewis Smith

The stated figures

$2.41 trillion
US annual cost of poor software quality
58%
developers citing time as a review challenge

The first quality rule in a codebase was a sentence in a shared document, and the enforcement mechanism was a senior engineer reading diffs. Teams wrote down how variables were named and how deep code was indented, then checked every change against the page, because a compiler reports only what stops a build. The page did not scale. One large change cost an afternoon of reading, and two reviewers applying the same sentence reached different verdicts. Tooling arrived when parsing grew cheap enough to walk a syntax tree, and it took over one narrow slice of that work.

The slice is narrower than the marketing suggests. Rules divide into two kinds:

Only the first kind belongs in a gate. The second kind belongs in a review, attached to the name of the person who made the call. The steps below run in order, so each one hands a smaller diff to the next, and a change that fails at any step never reaches the reviewer at the end of the chain.

The cost is measured. Codacy's guide to coding standards cites CISQ's 2022 estimate of $2.41 trillion a year for poor software quality in the United States, and reports that 58% of developers name time as the most common challenge they meet during code review. Both figures describe the same leak: review attention spent on questions a machine can settle.

Step 1. Pin one formatter and confirm the tree is clean

A formatter parses the file and prints it again. Same input, same output, which is the property that makes it safe to block a merge on. Codacy's guide names Prettier for JavaScript and Black for Python, and records that published style guides commonly cap a line at 80 or 120 characters. Choose one formatter per language, commit its configuration beside the code, and run it in check mode inside continuous integration:

prettier --check .
black --check .

Pass condition: exit code 0 and no filenames printed. A printed path means an editor is skipping format-on-save, so fix that configuration now, because every later step reports against formatted source.

Step 2. Turn linter warnings into a build failure

A linter walks the same syntax tree and applies rules to node types, which holds its cost per file flat as a repository grows. Codacy's guide names ESLint for JavaScript and Flake8 for Python. Set the warning budget to zero, keep the enabled rule list in version control, and require a rule ID plus a reason on every suppression comment. Which rules you adopt depends on what the product does. BrowserStack's guide to coding standards points at MISRA C and C++ for safety-critical automotive software and at CERT as the open, community-edited alternative, and that choice decides more about defect rates than the tool enforcing it.

gates:
  format: prettier --check .
  lint: eslint --max-warnings 0 .
  types: tsc --noEmit
  audit: npm audit --audit-level=high

Pass condition: eslint --max-warnings 0 . exits 0, and every suppression in the diff carries a rule and a reason. A suppression missing either field is a rule deleted by accident.

Step 3. Push type boundaries into the compiler

Type checking covers the defects a linter cannot express, such as a value that arrives shaped like something else. Addy Osmani's code review and quality skill tells a reviewer to question gratuitous any, unknown and optional types, and to read a silent fallback as an unclear invariant, because an explicit boundary removes the branching downstream of it. Run tsc --noEmit or mypy across the changed files.

The same file sets an approval standard worth copying: approve a change when it definitely improves the health of the codebase, even when it is not how you would have written it. That standard keeps a type gate from becoming a taste gate.

Pass condition: zero type errors on the files the change touches, and no new @ts-ignore, type: ignore or cast added to the diff.

Step 4. Break the tests on purpose

A green suite records that the tests executed, which is a weaker claim than the one reviewers read into it. The agent-skills review file settles the regression question by experiment: invert one condition the change adds, swap && for ||, run the suite, then restore the file from a copy. A suite that stays green after the inversion is a finding, and the finding is the name of the test case that should have failed. Breadth gets checked in the same pass. Documatic's guide to coding standards on dev.to splits coverage into unit, integration, regression and security tests, and asks for the failure path of an API call to be tested alongside the success path.

Pass condition: the inverted build fails at least one test, and the restored build passes.

Step 5. Gate dependency changes one package at a time

npm audit --audit-level=high returns a non-zero exit when a high or critical advisory matches an installed package, which makes it the cheapest gate in the pipeline. The agent-skills file treats every dependency as a liability and asks for one dependency per change, because a bulk bump that breaks the build leaves nobody able to name the package responsible. Read the changelog as well as the version number, since a patch release can carry a behavioural change the maintainer's promise did not cover. Review the lockfile diff as well as the manifest, because one direct bump can pull in dozens of indirect ones, and the lockfile is what pins what ships. Codacy's guide adds secrets and deprecated protocols to the same scan.

Pass condition: the audit exits 0, the pull request touches one direct dependency or a small related group, and someone has read the lockfile diff.

Step 6. Score the change against a size threshold

The thresholds below come from the code review and quality skill in Addy Osmani's agent-skills repository, which also treats a file that grows past about 1,000 total lines as an inspection signal.

Lines changed Verdict Action
about 100 Good Review in one sitting
about 300 Acceptable as one logical change Keep it as one change
about 1,000 Too large Split it

Pass condition: the diff sits inside a threshold, or the author has split it into parts that each pass on their own.

Step 7. Label every comment and order by leverage

Unlabelled feedback reads as mandatory, so optional notes compete with blocking ones for the same attention. The agent-skills review file fixes five prefixes, Critical, Required, Optional, Nit and FYI, and states that a comment carrying no prefix is required before merge. It scores a change on five axes, correctness, readability, architecture, security and performance, and it sets one business day as the maximum time to answer a review request, with findings ordered so correctness and security come first.

Pass condition: every comment carries a prefix, and the most severe comment sits at the top of the thread.

Step 8. Track the cycle and delete one rule a month

Graphite's code quality guidelines list maintainability, efficiency and reliability as the attributes a review protects, and Graphite Insights records the average number of review cycles until merge, which turns a vague complaint about slow review into a number a team can move. Take whichever of those three attributes is weakest in your repository, record the cycle count every week, and retire one enabled rule for each rule that joins the list.

Pass condition: the number is recorded weekly, and the enabled rule count does not grow.

A code quality tool does four things: parse a file, apply a rule, print a result, exit with a status. Every gate above is that loop with a threshold attached. A rule no parser can check belongs on a review checklist with a name against it, and a rule no person can check belongs in no document at all.

Sources

The figures behind this

US poor software cost
$2.41 trillion
Review time challenge
58% (Codacy)
Standard line length
80 or 120 chars

Related guides

Static Code Analysis Tools: Where to Start
Static Code Analysis Tools: Where to Start
How to Evaluate Code Review Platforms
How to Evaluate Code Review Platforms
Debugging Tools For Developers: What to Look For
Debugging Tools For Developers: What to Look For

← All Guides