Skip to main content
interlace
Plugin: conventionsRules

no-commented-code

Disallow commented-out code: delete it and let version control keep the history.

Disallow commented-out code (SonarQube RSPEC-125).

Quick Summary

AspectDetails
SeverityWarning (code quality)
Auto-Fix❌ No
CategoryQuality
Suggestions💡 Remove the comment

Rule Details

Commented-out code rots. It is not compiled, not tested and not refactored with the code around it, so it is wrong by the time anyone reads it, and version control already keeps every line ever deleted.

The rule reports a comment whose lines are code copied from source: a declaration (const total = sum(items);), a call statement (client.connect();), an import or export, a throw new …, an arrow function, a JSX element. A // line, a run of adjacent // lines (reported once, as one block) and a /* … */ block are all read.

It does not report:

  • Prose, even prose that opens with a keyword (// for backward compatibility, // if no key is passed, all cookies are returned) or ends in a parenthetical (// Retries the request (see the retry docs)). Copied code keeps its punctuation; a sentence does not end like a statement.
  • Links (// https://example.com/docs) and TODO / FIXME / HACK / XXX lines.
  • JSDoc blocks (/** … */): an @example body is the one place a comment is meant to hold code.

Options

OptionTypeDefaultDescription
ignoreSingleLinebooleanfalseDo not report a lone // line (a run of them still counts)
minLinesnumber1Report only comments (or runs of comments) at least this long
ignoreInTestsbooleantrueReport nothing in *.test.* / *.spec.* files

Examples

❌ Incorrect

// const total = sum(items);
// client.connect();

/*
 * import { legacy } from './legacy';
 * legacy.run();
 */

✅ Correct

// for widget and idx-js backward compatibility
// Retries the request (see the retry docs)
// https://example.com/docs/retries

/**
 * Adds the items.
 * @example
 * sum([1, 2]);
 */

Configuration Examples

Basic Usage

// eslint.config.mjs
export default [
  {
    rules: {
      'conventions/no-commented-code': 'warn',
    },
  },
];

Only multi-line blocks

{
  rules: {
    'conventions/no-commented-code': ['warn', { ignoreSingleLine: true, minLines: 2 }],
  },
}

Further Reading

Known False Negatives

  • A fragment without a statement terminator (// x = 1) is not reported: without the punctuation it cannot be told apart from prose.
  • Code inside a JSDoc block is never reported, even when it is not an @example.

Use this rule

npm install -D oxlint-plugin-conventions
.oxlintrc.json
{  "jsPlugins": ["oxlint-plugin-conventions"],  "rules": {    "conventions/no-commented-code": "error"  }}
vite.config.ts
import { defineConfig } from 'vite-plus';export default defineConfig({  lint: {    jsPlugins: ['oxlint-plugin-conventions'],    rules: {      'conventions/no-commented-code': 'error',    },  },});

oxlint-plugin-conventions re-exports eslint-plugin-conventions/oxlint: the same rules under the same IDs, and no ESLint install. Why oxlint.

Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.