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-vibe-proof

v1.7.1

Published

An ESLint plugin that tries its best to prevent your coding agents from pooping your bed.

Downloads

14,396

Readme

eslint-plugin-vibe-proof

You just can't really teach coding agents how to write the correct code using agent skills. The more agent skills you install, the faster models fill up the context window, and the faster your coding agents become stupid.

LLM when the context window usage hit 60%: wojak trying to put a square block into a round hole meme

And LLM is very good at forgetting things. Given a long last coding session and enough conversation compaction, your coding agents can and will eventually forget the important things like agent skills you installed, and even your AGENTS.md.

What you really need is a deterministic and unforgiving feedback loop for your coding agents. Unit tests and static analysis are exactly that. When your coding agents poop your bed, linter will not forgive, linter will not forget, linter will not yield, linter will not be constrained by the context window, linter will always detect and spit out the errors.

That's what eslint-plugin-vibe-proof is trying to accomplish here. It will detect the most common coding agents' mistakes and bad patterns, enforce LLM to write the correct code.

Installation

pnpm add eslint-plugin-vibe-proof
yarn add eslint-plugin-vibe-proof
npm install eslint-plugin-vibe-proof

Usage

You can begin by importing presets in your ESLint flat configuration. All presets are non-overlapping, so you can and should mix and use multiple of them.

import { eslint_plugin_vibe_proof } from 'eslint-plugin-vibe-proof';

/* basic presets that does not require typed linting */
eslint_plugin_vibe_proof.configs.common;
/* extra rules that require typescript-eslint typed linting */
eslint_plugin_vibe_proof.configs.common_type_checked;
/* react-specific rules */
eslint_plugin_vibe_proof.configs.react;
/* extra react-specific rules that require typescript-eslint typed linting */
eslint_plugin_vibe_proof.configs.react_type_checked;

You can also register the plugin and enable rules in your ESLint flat configuration yourself:

import { eslint_plugin_vibe_proof } from 'eslint-plugin-vibe-proof';

export default [
  {
    plugins: {
      'vibe-proof': eslint_plugin_vibe_proof
    },
    rules: {
      /* --- included in `configs.common` --- */

      // Ban `eslint-disable` comment directives that coding agents may use to
      // "workaround" linting errors, forcing them to write a description instead
      'vibe-proof/ban-eslint-disable': 'error',
      // Prefer `.reduce` over chaining `.filter` and `.map`
      'vibe-proof/no-chain-array-higher-order-functions': 'error',
      // Disallow `.includes()` on constant arrays — use a `Set` with `.has()`
      'vibe-proof/no-constant-array-includes': 'error',
      // Prefer `array.at(-1)` over `array[array.length - 1]` for the last item
      'vibe-proof/prefer-array-at-for-last-item': 'error',
      // Prefer `Array.from(iterable, mapper)` over materializing an iterable
      // and then calling `.map()`
      'vibe-proof/prefer-array-from-mapper': 'error',
      // Avoid passing entry arrays from `.flatMap()` / `.map()` / `.reduce()`
      // / `.reduceRight()` to `Object.fromEntries`
      'vibe-proof/prefer-array-reduce-to-object': 'error',
      // Prefer `.some()` over `.find()` / `.filter().length` when checking
      // whether an element exists
      'vibe-proof/prefer-array-some': 'error',
      // Prefer `export const { a, b } = value` over exporting elements one by one
      'vibe-proof/prefer-export-destructuring': 'error',
      // Hoist literal regexes to module level to avoid re-creation on every call
      'vibe-proof/prefer-hoisted-regex': 'error',
      // Hoist an `Intl.Collator` instance instead of calling `localeCompare`
      // inside a sort callback
      'vibe-proof/prefer-static-collator': 'error',
      // Prefer the fastest Unicode-safe code-unit / code-point operation for
      // statically known values
      'vibe-proof/prefer-string-code-point-operations': 'error',
      // Prefer `{ throwIfNoEntry: false }` over relying on a thrown error for
      // missing fs entries in sync stat calls
      'vibe-proof/prefer-throw-if-no-entry': 'error',
      // Pass the callback and its arguments directly to `setTimeout` /
      // `setInterval` instead of wrapping them in an arrow function or `bind`
      'vibe-proof/prefer-timer-args': 'error',

      /* --- included in `configs.common_type_checked` (requires typed linting) --- */

      // Prefer optimized alternatives (`.startsWith()`, direct index access)
      // over `indexOf()` equality checks
      'vibe-proof/no-indexof-equality': 'error',
      // Enforce indexed `for` loops with a cached length over `for...of` on arrays
      'vibe-proof/prefer-indexed-array-loop': 'error',

      /* --- included in `configs.react` --- */

      // Disallow duplicate JSX props — only the last one takes effect
      'vibe-proof/jsx-no-duplicate-props': 'error',
      // Disallow spreading object literals in JSX
      'vibe-proof/jsx-no-explicit-spread-props': 'error',
      // Disallow `location.href =` / `location.assign()` for relative-URL
      // navigation — use the framework's navigation API
      'vibe-proof/no-location-assign-relative-destination': 'error',
      // Disallow mirroring props, state, or hook returns into a ref to peek at later
      'vibe-proof/react-ban-peak-via-ref': 'error',
      // Detect unguarded state updates after async work inside an effect
      'vibe-proof/react-detect-potential-race-condition': 'error',
      // Detect circular dependencies in React effects
      'vibe-proof/react-no-circular-effect': 'error',
      // Disallow manual cancellation flags in `useEffect` for race condition cleanup
      'vibe-proof/react-no-manual-use-effect-race-condition-prevention': 'error',
      // Disallow mixing controlled and uncontrolled props on the same element
      'vibe-proof/react-no-mixing-controlled-and-uncontrolled-props': 'error',
      // Disallow `Array.prototype.find` in render, `useMemo`, or `useCallback`
      'vibe-proof/react-no-performance-impacting-array-find': 'error',
      // Disallow props that accept render functions returning JSX
      'vibe-proof/react-no-render-function-prop': 'error',
      // Disallow unnecessary `useCallback` calls
      'vibe-proof/react-no-unnecessary-use-callback': 'error',
      // Disallow unnecessary `useMemo` calls
      'vibe-proof/react-no-unnecessary-use-memo': 'error',
      // Disallow calling a `useState` setter synchronously in an effect
      'vibe-proof/react-no-use-effect-watching': 'error',
      // Disallow `useState` without its setter — use `useRef` or `foxact/use-singleton`
      'vibe-proof/react-no-use-state-as-ref': 'error',
      // Prefer `React.PropsWithChildren` over manually declaring `{ children: ReactNode }`
      'vibe-proof/react-prefer-props-with-children': 'error',
      // Prefer the state updater function form when updating state
      'vibe-proof/react-prefer-state-updater-function': 'error',

      // Prefer `ComposeContextProvider` when many providers are nested together
      'vibe-proof/react-prefer-foxact-compose-context-provider': 'error',
      // Disallow `localStorage` / `sessionStorage` in React code
      'vibe-proof/react-prefer-foxact-persistent': 'error',
      // Prefer an abortable effect for EventTarget subscriptions with manual cleanup
      'vibe-proof/react-prefer-foxact-use-abortable-effect': 'warn',
      // Disallow copy-related Web APIs in React code
      'vibe-proof/react-prefer-foxact-use-clipboard': 'error',
      // Disallow direct `matchMedia` usage in React code
      'vibe-proof/react-prefer-foxact-use-media-query': 'error'
    }
  }
];

License

MIT


eslint-plugin-vibe-proof © Sukka, Released under the MIT License. Authored and maintained by Sukka with help from contributors (list).

Personal Website · Blog · GitHub @SukkaW · Telegram Channel @SukkaChannel · Mastodon @[email protected] · Twitter @isukkaw · BlueSky @skk.moe