What Is a Linter? How It Checks AI-Written Code
A linter reads code without running it and flags likely mistakes. Why it is a cheap safety net for code an AI agent wrote.
A linter is a tool that reads your code without running it and flags patterns that are probably mistakes, such as a variable you never use, a comparison that always evaluates the same way, or a function that may return nothing on one path. It is quick, free and runs in seconds, which makes it one of the cheapest checks you can put between an AI coding agent and your main branch.
What a linter actually does
The ESLint documentation describes its tool as one for identifying and reporting on patterns found in ECMAScript and JavaScript code, and says it is completely pluggable. Other languages have their own: Ruff for Python, Clippy for Rust, and so on. The principle is shared. The tool parses the code into a structure, checks it against a list of rules, and reports each violation with a line number.
It does not run your program. That is the point. A unit test proves a behaviour works for the inputs you tried, while a linter looks at the code's shape and finds problems no test happens to exercise.
A small example
function total(items) {
let sum = 0;
let count = items.length;
for (const item of items) {
if (item.price = 0) {
continue;
}
sum += item.price;
}
return sum;
}Two problems are hiding here. The variable count is assigned and never used. More seriously, item.price = 0 is an assignment inside a condition, where a comparison was almost certainly meant. It would also overwrite every price with zero. The code is valid, it runs, and a casual read can miss it. A linter with the usual recommended rules flags both lines immediately.
This kind of slip is common in generated code, because the model is producing plausible text, not checking intent.
Run one in five minutes
For a JavaScript project, the ESLint docs give a setup command:
npm init @eslint/config@latestIt asks a few questions and writes a config file, eslint.config.js. Then check a file:
npx eslint yourfile.jsThe project needs a package.json first. Once it works, add a lint script so the agent and your CI can both call it the same way.
Linter, formatter, type checker
These three get mixed up, and an agent will happily run the wrong one.
Tool | Question it answers | Example |
|---|---|---|
Linter | Is this code likely wrong or risky? | ESLint |
Is this laid out consistently? | Prettier | |
Type checker | Do the values fit the types? | TypeScript |
Use all three. They overlap a little and catch different things.
Handing lint errors to an agent
Asking an agent to "fix the lint errors" works well, with one trap. The shortest route to a clean run is often to disable the rule or add an ignore comment. Say so in your instruction:
Paste the exact lint output, not a summary.
Ask for the fix to the code, and say that disabling rules or adding ignore comments is not allowed unless you approve it.
Re-run the linter yourself and check the diff for new
eslint-disablelines.
You can also run the linter automatically before each commit, as described in setting up a pre-commit hook with an AI code reviewer. For choosing the tools around it, see the AI coding tools guide.
What a linter will not catch
It cannot tell you the code does the wrong thing correctly. A function that cleanly computes the wrong discount passes every lint rule. It also misses design problems, slow queries and bad naming. Treat a clean lint run as the floor, not a sign of quality.
Frequently asked questions
What does a linter do?
It analyses source code without running it and reports likely bugs, risky patterns and rule violations, usually with the file and line number.
Is ESLint a linter or a formatter?
ESLint is a linter. It identifies and reports on patterns in JavaScript code. Layout is the job of a formatter.
Do I need a linter if I have tests?
Yes. Tests check behaviour for the cases you wrote. A linter finds structural mistakes in code paths your tests may never reach.
Should I let an AI agent fix lint errors?
Yes, with a rule that it must change the code and not disable the check, and with your own re-run of the linter afterwards.
How did this land?
About the author

Staff Engineer, Platform
Carlo works on the platform that turns prompts into running apps. He writes the engineering deep dives and the changelog notes worth reading.


