Skip to main content
aislop does not ban comments. It bans comments that make code noisier without adding information. Keep comments that explain a non-obvious constraint, an external workaround, a data contract, or an invariant the type system cannot express. Delete comments that repeat nearby code.

Decision tree

Run every comment through this checklist before keeping it.
1

Check the name first

If the function, variable, or file name already says what the comment says, delete the comment. Rename the symbol if the name is weak.
2

Delete what-comments

Comments that describe what the next line does are usually redundant. The code is already the source of truth for what happens.
3

Keep why-comments

Keep short notes that explain a non-obvious reason: a third-party bug, a protocol constraint, a compatibility workaround, or an invariant reviewers cannot infer locally.

Bad and good examples

Trivial restatement

Bad:
// Initialize the user service
const userService = new UserService();
Good:
const userService = new UserService();
The name already says what the comment says.

Narrative JSDoc

Bad:
/**
 * Heuristic side-effect detection. Walks an expression subtree
 * and flags anything that could invoke code when the declaration
 * initializes.
 */
export const hasSideEffect = (node: Node): boolean => {
  // ...
};
Good:
/**
 * @deprecated Use {@link hasObservableEffect}. This predicate
 * under-counts dynamic property access.
 */
export const hasSideEffect = (node: Node): boolean => {
  // ...
};
The first block restates the function. The second carries a contract that editors and callers can use.

Decorative separators

Bad:
// --- Classification -------------------------------------------------
// Per-engine planning, building rows from a discovered project
// -------------------------------------------------------------------
export const classify = () => {
  // ...
};
Good:
export const classify = () => {
  // ...
};
If a file needs section banners to stay readable, split it into smaller files.

Phase headers

Bad:
// Phase 1: Code changes
await runLint();
await runDeps();

// Phase 2: Formatting
await runFormat();
Good:
await runLint();
await runDeps();

await runFormat();
Whitespace already groups the steps.

JSDoc that earns its place

Keep JSDoc when it has machine-readable value or explains a public contract.
KeepWhy
@deprecatedEditors and type tooling can warn callers
@see / @linkTyped references survive renames better than prose
@exampleUseful for public APIs and library exports
@param / @returnsUseful only when the semantic meaning is not obvious from the name and type
Delete JSDoc that summarizes an internal helper, repeats parameter names, or narrates implementation steps.

Rules involved

RuleWhat it flagsFixable
ai-slop/trivial-commentAdjacent comments that restate codeYes
ai-slop/narrative-commentDecorative banners, phase headers, JSDoc preambles without meaningful tags, and AI-narration proseYes
ai-slop/meta-commentComments about implementation phases, generated-code process, or agent behaviorUsually
Run:
aislop fix
The fixer removes comments that are mechanically safe to delete and verifies the file still parses before writing the result.