You shouldn't be writing comments. And if you do, here's how.
The best comment is the one you didn't need to write. This page covers when a comment earns its place, when it's dead weight, and what aislop removes for you.
When a comment earns its place
Run every comment through this decision tree before you keep it.
- 1.Does the function or variable name already say this? If yes, delete the comment. Rename the symbol if the name is weak.
- 2.Is this describing WHAT the code does? Delete it. The code describes what the code does.
- 3.Is this the WHY? A non-obvious constraint, an external bug workaround, an invariant the compiler can't prove. Keep it. Keep it short.
Good comments answer questions the reader will ask and the code can't answer. Bad comments answer questions nobody was going to ask.
Good vs bad. Five pairs
Each example is real. Every "bad" block is something we removed from our own codebase during aislop 0.5 development.
The name already says what the comment says. The comment is a tax on every future read.
The first is a summary of what the function does. The reader could deduce that from the name and body. The second tells the reader something they cannot see.
If you need to separate sections of a file, it's two files. The filesystem is a much better structural tool than ASCII art.
The blank line already says "these are two groups." A reader who needs to know that formatting runs last reads the code top-to-bottom.
The comment describes how two lines of code coordinate. The code itself already shows the coordination. When one line changes the comment rots silently, and nobody updates it.
JSDoc: when and when not
JSDoc earns its place when it carries machine-readable signal that the code cannot. Keep these:
- +
@deprecated. The linter enforces it, editors underline callers. - +
@see/@link. Typed cross-references that survive renames. - +
@example. Shown in hover tooltips; especially valuable on external APIs. - +
@param/@returns. Only when the parameter's semantic meaning isn't obvious from its type.
Delete these:
- − A prose paragraph that summarizes the function body.
- −
@param name The name. Restating the parameter name is not documentation. - − JSDoc on internal-only helpers. If nobody outside the file calls it, it doesn't need a public contract.
What aislop catches automatically
Two rules handle the common cases:
| Rule | What it flags |
|---|---|
| ai-slop/trivial-comment | Comments that restate their adjacent line of code. |
| ai-slop/narrative-comment | Decorative separators, phase headers, multi-line preambles, cross-reference commentary, JSDoc narration. |
Run aislop fix and both rules will strip matches in place. The fixer AST-verifies the file still parses before writing, and reverts on any mismatch. See the full rules reference.
We caught ourselves. Here's how.
We wrote aislop. Then, during the 0.5 rehaul, we extended it with new engines, a new fix pipeline, a CLI redesign. In the process, an AI agent (working with one of us) added about seventy narrative and decorative comments to the aislop source: section banners, phase headers, multi-line preambles above function declarations, JSDoc paragraphs that summarized what the function body did.
We noticed. We added the ai-slop/narrative-comment rule. Then we ran our own tool against our own source:
The tool-builder needed the rule. You probably do too.