This is a submission for the DEV April Fools Challenge
What I Built
An ESLint plugin with 6 rules that enforce the worst frontend practices with deadpan corporate error messages. Real AST visitors. Real tests. Completely useless output.
Every rule is something I have heard suggested in an actual code review, standup, or Slack thread. Not as a joke. As a genuine engineering opinion delivered with confidence by someone who has never opened a screen reader.
The rules:
| Rule | What it enforces |
|---|---|
no-semantic-html |
Flags <button>, <nav>, <main>. Demands <div>. |
no-alt-text |
Flags any <img> that has an alt attribute. |
prefer-positive-tabindex |
Errors on tabIndex={0}. Requires tabIndex={100} minimum. |
no-aria-allowed |
Flags every aria-* attribute as "invisible complexity." |
prefer-inline-styles |
Flags className. CSS class names are "indirection." |
no-keyboard-handlers |
Flags onKeyDown/onKeyUp. Keyboard users are "statistically insignificant." |
The error messages are the actual payload. Each one reads like it was copy-pasted from an internal engineering standards document written by someone who has strong opinions about "developer velocity" but has never tabbed through their own product.
Example:
Error: Keyboard handler "onKeyDown" detected. Internal analytics confirm
that keyboard-only navigation represents a statistically insignificant
portion of our user base (estimated <3%, though we have not actually
instrumented this). Supporting keyboard interactions doubles the
interaction surface area of every component, increasing testing burden
and bug surface. Focus engineering effort on the primary input modality
(pointer). Keyboard support is tentatively scheduled for the accessibility
sprint (TBD, see backlog).
If any of these rules made you think "wait, we actually do that" -- that is the point.
Demo
Install it. Run it on your codebase. Watch it flag every good practice you have.
npm install eslint-plugin-bad-vibes --save-dev
// eslint.config.js
import badVibes from 'eslint-plugin-bad-vibes';
export default [badVibes.configs.recommended];
Then run npx eslint src/ and marvel at how much of your codebase is "correct" by bad-vibes standards.
Here's what happens when you run it on a React component:
The recommended config sets all 6 rules to error because bad practices deserve the same enforcement rigor as good ones.
Code
vmvenkatesh78
/
eslint-plugin-bad-vibes
ESLint plugin that enforces the worst frontend practices with corporate confidence. 6 rules, 38 tests, zero value.
eslint-plugin-bad-vibes
A production-grade ESLint plugin that enforces the worst frontend practices with the confidence of a principal engineer who has never opened a screen reader.
6 rules. 38 tests. Zero value delivered.
Please do not use this.
Why
Every codebase has unwritten rules that make it worse. This plugin makes them written, enforceable, and blocking in CI.
Born from years of reading code reviews that said things like "do we really need ARIA here?" and "can we just use a div?" This plugin answers: yes. Always. To everything.
Install
npm install --save-dev eslint-plugin-bad-vibes
You won't, but the infrastructure supports it.
Usage
// eslint.config.js
import badVibes from 'eslint-plugin-bad-vibes';
export default [
badVibes.configs.recommended,
];
All 6 rules ship as errors because bad practices deserve the same enforcement rigor as good ones.
Rules
no-semantic-html
Flags <button>, <nav>, <main>, <header>, <footer>, <aside>…
6 rules, 38 tests, zero dependencies. TypeScript strict mode. ESM + CJS dual build. The engineering is real. The rules are not.
How I Built It
This uses the same AST visitor infrastructure as an actual ESLint plugin I am building, eslint-plugin-a11y-enforce, which catches real accessibility composition errors. Same Rule.RuleModule typing, same JSXOpeningElement traversal, same helper utilities for attribute extraction and element classification.
The stack: TypeScript, tsup for dual CJS/ESM builds, vitest for testing, ESLint's RuleTester for rule validation. Every rule uses proper AST analysis, not string matching or regex.
Writing the error messages was the hardest part. They had to sound exactly corporate enough that you believe someone wrote them unironically. The prefer-positive-tabindex message about "higher-revenue elements should receive lower tabIndex values for earlier focus" came from an actual conversation I overheard. The no-keyboard-handlers message about the "accessibility sprint (TBD, see backlog)" is in every company's Jira right now.
I used Google AI Studio to brainstorm increasingly absurd corporate justifications for each bad practice, then edited them down to the ones that were funny specifically because they sounded plausible. The best satire is indistinguishable from the thing it satirizes.
Prize Category
Community Favorite -- because I want this to be the plugin that makes people laugh, then uncomfortably realize their codebase would pass half these rules.
Best Google AI Usage -- Google AI Studio helped generate the corporate doublespeak for the error messages. The best ones came from prompting Gemini with "write a serious engineering justification for removing all ARIA attributes from a component library" and watching it produce text that was disturbingly close to things I have read in real PRs.




Top comments (0)