npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

eslint-plugin-no-comment-slop

v0.3.0

Published

Flags AI comment slop in JavaScript and TypeScript. Runs in ESLint, oxlint and rslint

Readme

eslint-plugin-no-comment-slop

Flags AI comment slop in JavaScript and TypeScript. The same module runs unchanged in ESLint, oxlint and rslint because it only uses the rule APIs all three linters implement. CI runs one fixture through eslint 9, eslint 10, oxlint and rslint and requires identical diagnostics.

Before:

// ============================================
// Utilize this robust helper to seamlessly retrieve the user — it is
// crucial to note that it delves into the cache first.
export const getUser = (id) => cache.get(id) ?? fetchUser(id); // fetches the user

After:

/**
 * Cache first, network second
 */
export const getUser = (id) => cache.get(id) ?? fetchUser(id);

Install

npm install --save-dev eslint-plugin-no-comment-slop

Needs Node 24+ and one of: ESLint 9+ with flat config, oxlint with jsPlugins, or rslint.

Usage

ESLint (eslint.config.mjs):

import noCommentSlop from "eslint-plugin-no-comment-slop";

export default [noCommentSlop.configs.recommended];

To adjust a rule, override it after the preset:

export default [
  noCommentSlop.configs.recommended,
  {
    rules: {
      "no-comment-slop/no-trailing-period": "off",
      "no-comment-slop/no-jargon": ["error", { extraWords: ["synergy"] }],
    },
  },
];

Consider leaving tests alone. Generated tests often earn their comments: a line or two per unit or e2e case documents intent that would otherwise live nowhere. Whether to lint test comments is the maintainer's call; to skip them:

export default [
  {
    ...noCommentSlop.configs.recommended,
    ignores: ["**/*.test.*", "**/*.spec.*", "**/tests/**", "**/e2e/**"],
  },
];

oxlint (.oxlintrc.json) has no preset support for JS plugins, so enable each rule from the table below:

{
  "jsPlugins": ["eslint-plugin-no-comment-slop"],
  "rules": {
    "no-comment-slop/no-jargon": "error",
    "no-comment-slop/no-em-dash": "error"
  }
}

rslint (rslint.config.mjs):

import noCommentSlop from "eslint-plugin-no-comment-slop";

export default [
  {
    files: ["**/*.{js,ts}"],
    ...noCommentSlop.configs.recommended,
  },
];

Rules

Every rule is part of the recommended config. The 🔧 fixes are mechanical: delete a banner, drop a period, turn // into JSDoc. --fix never rewrites your wording; no-jargon and no-em-dash report with guidance instead.

🔧 Automatically fixable by the --fix CLI option.
💡 Manually fixable by editor suggestions.

| Name                     | Description | 🔧 | 💡 | | :----------------------------------------------------------------- | :------------------------------------------------------------------ | :- | :- | | max-comment-lines | Limit how many lines a comment may span | | | | multiline-jsdoc-format | Require /** and / on their own lines in a multi-line JSDoc comment | 🔧 | | | no-banner-comment | Disallow ASCII separator and banner comments | 🔧 | | | no-em-dash | Disallow em dashes (and optionally en dashes) in comments | | | | no-foreign-syntax | Disallow comment syntax imported from other languages | | | | no-jargon | Disallow inflated vocabulary in comments | | 💡 | | no-trailing-comment | Disallow comments on the same line as code | | | | no-trailing-period | Disallow a trailing period at the end of a comment | 🔧 | | | prefer-jsdoc-for-exports | Require /* / rather than // for the comment documenting an export | 🔧 | | | prefer-jsdoc-for-members | Require /* */ rather than // for the comment documenting a member | 🔧 | | | require-member-docs | Require docs on every member once most of a type is documented | | |

What it catches

One flagged example per rule. Each rule doc has the matching fix.

max-comment-lines — a wall of prose above one call:

// This helper computes the value by first checking the cache,
// then falling back to the network, then retrying twice with
// exponential backoff, and finally giving up and returning null
// so the caller can decide what to do next.
const value = load();

multiline-jsdoc-format — text hanging off the /** line:

/** Stamped into every artifact so files are self-describing.
 * Bump only on a breaking change */
export const schemaVersion = 3;

no-banner-comment — ASCII rulers and banners:

// ============================
// --- helpers ---
/* ************************** */

no-em-dash — the em dash aside:

// caches the value — see the loader

no-foreign-syntax — Rust and C# doc habits in JavaScript:

/// Returns the user id
// <summary>Gets the id</summary>
//#region helpers

no-jargon — inflated vocabulary:

// utilize the robust cache to streamline lookups

no-trailing-comment — a comment restating the line it sits on:

const retries = 3; // number of retries

no-trailing-period — a sentence-ending period on a one-line comment:

// waits for the lock before writing.

prefer-jsdoc-for-exports// above an export, which no editor shows on hover:

// Parses the config file
export function parseConfig(path) {}

prefer-jsdoc-for-members — the same for a member:

interface RecordOptions {
  // run without a window
  headless: boolean;
}

require-member-docs — one member left out once the rest are documented:

interface RecordOptions {
  /** module to load */
  module: string;
  /** entry function name */
  fn: string;
  /** browser binary */
  browser: string;
  url: string;
}

License

MIT