Skip to content

About

Fork from `jsx-eslint/eslint-plugin-react`. Main propose is maintaining dependencie updates. React-specific linting rules for ESLint

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

3,510 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@ysknsid25/eslint-plugin-react

npm version npm downloads GitHub last commit Tests: ESLint CI: lint & build Types License: MIT CodeRabbit Pull Request Reviews

React specific linting rules for eslint, as a maintained fork of eslint-plugin-react.

Why this fork

What you get Details
πŸ” Drop-in Same rules, same results The rules are registered under the same react/ namespace (e.g. react/jsx-key), and report exactly the same problems as the original (checked on every PR, see Benchmarks)
⚑ Performance Faster than the original ~12% faster with the all config, and about the same with recommended (CI checks that it is not more than 5% slower) (see Benchmarks)
⚑ Performance Regression check in CI Vitest Bench runs on every PR: it fails when the PR is more than 5% slower than the baseline or not faster than the original, and the comparison with the base branch is commented on the PR
🧩 Compatibility ESLint 10 Supports ESLint ^9.7 and ^10, tested on both in CI (the original does not support ESLint 10: e.g. its all config throws there)
🧩 Compatibility Current Node.js Node.js 22 or later, tested on 22, 24 and 26 in CI
πŸ“¦ Dependencies Only 3 runtime dependencies Polyfills are replaced with native APIs, and the needed part of jsx-ast-utils is included: 7 installed packages instead of 124, ~85% smaller install (see Package size)
πŸ“¦ Dependencies Kept up to date Dependabot updates the npm packages and the GitHub Actions every week
πŸ”’ Supply chain security Cooldown New versions of dependencies are installed only after 2 weeks (pnpm minimumReleaseAge, Dependabot cooldown), to avoid freshly published malicious versions
πŸ”’ Supply chain security Pinned GitHub Actions Every action is pinned to a full commit SHA, CI installs with a frozen lockfile, and the release workflow runs with harden-runner
πŸ”’ Supply chain security Staged publishing Releases are published with npm staged publishing: a staged package goes live only after it is approved with 2FA
πŸ› οΈ Contributing Modern toolchain pnpm, TypeScript 6, ESLint 10 with flat config, @stylistic/eslint-plugin as the formatter, Vitest 5 and Changesets
πŸ› οΈ Contributing Automated chores On PRs, CI applies pnpm lint:fix, regenerates the rule docs, comments the test coverage and the benchmark results, and checks that a changeset is included

Benchmarks

Linting the React code in bench/fixtures/ with each shareable config (bench/upstream.bench.mjs), on ESLint 9.39.5, Node.js 22.23.3 and Apple M2 (the original does not support ESLint 10). Higher is better. The numbers vary between runs and machines: run pnpm bench upstream in bench/ to measure them yourself.

Config This fork (ops/sec) eslint-plugin-react 7.37.5 (ops/sec) Difference
recommended 192.1 184.9 +3.9% (within the noise)
all 72.3 64.5 +12.1%
all (TypeScript) 144.8 132.6 +9.2%

Package size

This fork eslint-plugin-react 7.37.5
Runtime dependencies 3 18
Installed packages (including the plugin itself, without eslint) 7 124
Install size (total size of the installed files) 1.07 MB 7.32 MB
Unpacked size of the package 923 KB 938 KB

About this fork

This package is a fork of jsx-eslint/eslint-plugin-react. The rules themselves come from the original project, and all credit for them goes to its authors and contributors.

Supported versions:

  • ESLint: ^9.7 and ^10
  • Node.js: 22 or later

Differences from the original package:

  • The package is published as @ysknsid25/eslint-plugin-react.
  • Only the flat config (eslint.config.js) is supported. The legacy .eslintrc* configs of this plugin refer to the plugin as react, which resolves to the original eslint-plugin-react package instead of this one.

Inside your config, the plugin is still registered under the react namespace, so rule names are the same as in the original package (e.g. react/jsx-key). Do not install this package together with the original eslint-plugin-react in the same config, since both use the react namespace.

Installation

pnpm add -D eslint @ysknsid25/eslint-plugin-react

or

npm install --save-dev eslint @ysknsid25/eslint-plugin-react

Configuration

See the official docs for the flat config system (eslint.config.js).

Shareable configs

This plugin exports 3 flat configs:

  • flat.recommended: enforces React good practices
  • flat['jsx-runtime']: disables rules that are not needed with the new JSX transform from React 17
  • flat.all: includes every available rule

The flat configs are available via the root plugin import. They will configure the plugin under the react/ namespace and enable JSX in languageOptions.parserOptions.

const reactPlugin = require('@ysknsid25/eslint-plugin-react');

module.exports = [
  …
  reactPlugin.configs.flat.recommended, // This is not a plugin object, but a shareable config object
  reactPlugin.configs.flat['jsx-runtime'], // Add this if you are using React 17+
  …
];

You can of course add/override some properties.

Note: Our shareable configs does not preconfigure files or languageOptions.globals. For most of the cases, you probably want to configure some properties by yourself.

const reactPlugin = require('@ysknsid25/eslint-plugin-react');
const globals = require('globals');

module.exports = [
  …
  {
    files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
    ...reactPlugin.configs.flat.recommended,
    languageOptions: {
      ...reactPlugin.configs.flat.recommended.languageOptions,
      globals: {
        ...globals.serviceworker,
        ...globals.browser,
      },
    },
  },
  …
];

The above example is same as the example below, as the new config system is based on chaining.

const reactPlugin = require('@ysknsid25/eslint-plugin-react');
const globals = require('globals');

module.exports = [
  …
  {
    files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
    ...reactPlugin.configs.flat.recommended,
  },
  {
    files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
    languageOptions: {
      globals: {
        ...globals.serviceworker,
        ...globals.browser,
      },
    },
  },
  …
];

Plugin

If you do not use a shareable config, you will need to register the plugin, enable JSX support and specify individual rules. The default export of @ysknsid25/eslint-plugin-react is a plugin object.

const react = require('@ysknsid25/eslint-plugin-react');
const globals = require('globals');

module.exports = [
  …
  {
    files: ['**/*.{js,jsx,mjs,cjs,ts,tsx}'],
    plugins: {
      react,
    },
    languageOptions: {
      parserOptions: {
        ecmaFeatures: {
          jsx: true,
        },
      },
      globals: {
        ...globals.browser,
      },
    },
    rules: {
      // ... any rules you want
      'react/jsx-uses-react': 'error',
      'react/jsx-uses-vars': 'error',
     },
    // ... others are omitted for brevity
  },
  …
];

Configuring shared settings

You should also specify settings that will be shared across all the plugin rules. (More about eslint shared settings) Add a settings property like below to a config object in your eslint.config.js.

{
  "settings": {
    "react": {
      "createClass": "createReactClass", // Regex for Component Factory to use,
                                         // default to "createReactClass"
      "pragma": "React",  // Pragma to use, default to "React"
      "fragment": "Fragment",  // Fragment to use (may be a property of <pragma>), default to "Fragment"
      "version": "detect", // React version. "detect" automatically picks the version you have installed.
                           // You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
                           // Defaults to the "defaultVersion" setting and warns if missing, and to "detect" in the future
      "defaultVersion": "", // Default React version to use when the version you have installed cannot be detected.
                            // If not provided, defaults to the latest React version.
      "flowVersion": "0.53" // Flow version
    },
    "propWrapperFunctions": [
        // The names of any function used to wrap propTypes, e.g. `forbidExtraProps`. If this isn't set, any propTypes wrapped in a function will be skipped.
        "forbidExtraProps",
        {"property": "freeze", "object": "Object"},
        {"property": "myFavoriteWrapper"},
        // for rules that check exact prop wrappers
        {"property": "forbidExtraProps", "exact": true}
    ],
    "componentWrapperFunctions": [
        // The name of any function used to wrap components, e.g. Mobx `observer` function. If this isn't set, components wrapped by these functions will be skipped.
        "observer", // `property`
        {"property": "styled"}, // `object` is optional
        {"property": "observer", "object": "Mobx"},
        {"property": "observer", "object": "<pragma>"} // sets `object` to whatever value `settings.react.pragma` is set to
    ],
    "formComponents": [
      // Components used as alternatives to <form> for forms, eg. <Form endpoint={ url } />
      "CustomForm",
      {"name": "SimpleForm", "formAttribute": "endpoint"},
      {"name": "Form", "formAttribute": ["registerEndpoint", "loginEndpoint"]}, // allows specifying multiple properties if necessary
    ],
    "linkComponents": [
      // Components used as alternatives to <a> for linking, eg. <Link to={ url } />
      "Hyperlink",
      {"name": "MyLink", "linkAttribute": "to"},
      {"name": "Link", "linkAttribute": ["to", "href"]}, // allows specifying multiple properties if necessary
    ]
  }
}

List of supported rules

πŸ’Ό Configurations enabled in.
🚫 Configurations disabled in.
πŸƒ Set in the jsx-runtime configuration.
β˜‘οΈ Set in the recommended configuration.
πŸ”§ Automatically fixable by the --fix CLI option.
πŸ’‘ Manually fixable by editor suggestions.
❌ Deprecated.

NameΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β  Description πŸ’Ό 🚫 πŸ”§ πŸ’‘ ❌
async-server-action Require functions with the use server directive to be async πŸ’‘
boolean-prop-naming Enforces consistent naming for boolean props
button-has-type Disallow usage of button elements without an explicit type attribute
checked-requires-onchange-or-readonly Enforce using onChange or readonly attribute when checked is used
default-props-match-prop-types Enforce all defaultProps have a corresponding non-required PropType
destructuring-assignment Enforce consistent usage of destructuring assignment of props, state, and context πŸ”§
display-name Disallow missing displayName in a React component definition β˜‘οΈ
forbid-component-props Disallow certain props on components
forbid-dom-props Disallow certain props on DOM Nodes
forbid-elements Disallow certain elements
forbid-foreign-prop-types Disallow using another component's propTypes
forbid-prop-types Disallow certain propTypes
forward-ref-uses-ref Require all forwardRef components include a ref parameter πŸ’‘
function-component-definition Enforce a specific function type for function components πŸ”§
hook-use-state Ensure destructuring and symmetric naming of useState hook value and setter variables πŸ’‘
iframe-missing-sandbox Enforce sandbox attribute on iframe elements
jsx-boolean-value Enforce boolean attributes notation in JSX πŸ”§
jsx-child-element-spacing Enforce or disallow spaces inside of curly braces in JSX attributes and expressions
jsx-closing-bracket-location Enforce closing bracket location in JSX πŸ”§
jsx-closing-tag-location Enforce closing tag location for multiline JSX πŸ”§
jsx-curly-brace-presence Disallow unnecessary JSX expressions when literals alone are sufficient or enforce JSX expressions on literals in JSX children or attributes πŸ”§
jsx-curly-newline Enforce consistent linebreaks in curly braces in JSX attributes and expressions πŸ”§
jsx-curly-spacing Enforce or disallow spaces inside of curly braces in JSX attributes and expressions πŸ”§
jsx-equals-spacing Enforce or disallow spaces around equal signs in JSX attributes πŸ”§
jsx-filename-extension Disallow file extensions that may contain JSX
jsx-first-prop-new-line Enforce proper position of the first property in JSX πŸ”§
jsx-fragments Enforce shorthand or standard form for React fragments πŸ”§
jsx-handler-names Enforce event handler naming conventions in JSX
jsx-indent Enforce JSX indentation πŸ”§
jsx-indent-props Enforce props indentation in JSX πŸ”§
jsx-key Disallow missing key props in iterators/collection literals β˜‘οΈ
jsx-max-depth Enforce JSX maximum depth
jsx-max-props-per-line Enforce maximum of props on a single line in JSX πŸ”§
jsx-newline Require or prevent a new line after jsx elements and expressions. πŸ”§
jsx-no-bind Disallow .bind() or arrow functions in JSX props
jsx-no-comment-textnodes Disallow comments from being inserted as text nodes β˜‘οΈ
jsx-no-constructed-context-values Disallows JSX context provider values from taking values that will cause needless rerenders
jsx-no-duplicate-props Disallow duplicate properties in JSX β˜‘οΈ
jsx-no-leaked-render Disallow problematic leaked values from being rendered πŸ”§
jsx-no-literals Disallow usage of string literals in JSX
jsx-no-script-url Disallow usage of javascript: URLs
jsx-no-target-blank Disallow target="_blank" attribute without rel="noreferrer" β˜‘οΈ πŸ”§
jsx-no-undef Disallow undeclared variables in JSX β˜‘οΈ
jsx-no-useless-fragment Disallow unnecessary fragments πŸ”§
jsx-one-expression-per-line Require one JSX element per line πŸ”§
jsx-pascal-case Enforce PascalCase for user-defined JSX components
jsx-props-no-multi-spaces Disallow multiple spaces between inline JSX props πŸ”§
jsx-props-no-spread-multi Disallow JSX prop spreading the same identifier multiple times
jsx-props-no-spreading Disallow JSX prop spreading
jsx-sort-default-props Enforce defaultProps declarations alphabetical sorting ❌
jsx-sort-props Enforce props alphabetical sorting πŸ”§
jsx-space-before-closing Enforce spacing before closing bracket in JSX πŸ”§ ❌
jsx-tag-spacing Enforce whitespace in and around the JSX opening and closing brackets πŸ”§
jsx-uses-react Disallow React to be incorrectly marked as unused β˜‘οΈ πŸƒ
jsx-uses-vars Disallow variables used in JSX to be incorrectly marked as unused β˜‘οΈ
jsx-wrap-multilines Disallow missing parentheses around multiline JSX πŸ”§
no-access-state-in-setstate Disallow when this.state is accessed within setState
no-adjacent-inline-elements Disallow adjacent inline elements not separated by whitespace.
no-array-index-key Disallow usage of Array index in keys
no-arrow-function-lifecycle Lifecycle methods should be methods on the prototype, not class fields πŸ”§
no-children-prop Disallow passing of children as props β˜‘οΈ
no-danger Disallow usage of dangerous JSX properties
no-danger-with-children Disallow when a DOM element is using both children and dangerouslySetInnerHTML β˜‘οΈ
no-deprecated Disallow usage of deprecated methods β˜‘οΈ
no-did-mount-set-state Disallow usage of setState in componentDidMount
no-did-update-set-state Disallow usage of setState in componentDidUpdate
no-direct-mutation-state Disallow direct mutation of this.state β˜‘οΈ
no-find-dom-node Disallow usage of findDOMNode β˜‘οΈ
no-invalid-html-attribute Disallow usage of invalid attributes πŸ’‘
no-is-mounted Disallow usage of isMounted β˜‘οΈ
no-multi-comp Disallow multiple component definition per file
no-namespace Enforce that namespaces are not used in React elements
no-object-type-as-default-prop Disallow usage of referential-type variables as default param in functional component
no-redundant-should-component-update Disallow usage of shouldComponentUpdate when extending React.PureComponent
no-render-return-value Disallow usage of the return value of ReactDOM.render β˜‘οΈ
no-set-state Disallow usage of setState
no-string-refs Disallow using string references β˜‘οΈ
no-this-in-sfc Disallow this from being used in stateless functional components
no-typos Disallow common typos
no-unescaped-entities Disallow unescaped HTML entities from appearing in markup β˜‘οΈ πŸ’‘
no-unknown-property Disallow usage of unknown DOM property β˜‘οΈ πŸ”§
no-unsafe Disallow usage of unsafe lifecycle methods β˜‘οΈ
no-unstable-nested-components Disallow creating unstable components inside components
no-unused-class-component-methods Disallow declaring unused methods of component class
no-unused-prop-types Disallow definitions of unused propTypes
no-unused-state Disallow definitions of unused state
no-will-update-set-state Disallow usage of setState in componentWillUpdate
prefer-es6-class Enforce ES5 or ES6 class for React Components
prefer-exact-props Prefer exact proptype definitions
prefer-read-only-props Enforce that props are read-only πŸ”§
prefer-stateless-function Enforce stateless components to be written as a pure function
prop-types Disallow missing props validation in a React component definition β˜‘οΈ
react-in-jsx-scope Disallow missing React when using JSX β˜‘οΈ πŸƒ
require-default-props Enforce a defaultProps definition for every prop that is not a required prop
require-optimization Enforce React components to have a shouldComponentUpdate method
require-render-return Enforce ES5 or ES6 class for returning value in render function β˜‘οΈ
self-closing-comp Disallow extra closing tags for components without children πŸ”§
sort-comp Enforce component methods order
sort-default-props Enforce defaultProps declarations alphabetical sorting
sort-prop-types Enforce propTypes declarations alphabetical sorting πŸ”§
state-in-constructor Enforce class component state initialization style
static-property-placement Enforces where React component static properties should be positioned.
style-prop-object Enforce style prop value is an object
void-dom-elements-no-children Disallow void DOM elements (e.g. <img />, <br />) from receiving children

Other useful plugins

Development

This repository uses pnpm only (the version is pinned in devEngines.packageManager of package.json, and npm install / npm run fail on purpose).

pnpm install
pnpm lint      # markdownlint, eslint-doc-generator --check, eslint, tsc
pnpm lint:fix  # format with @stylistic/eslint-plugin (eslint --fix)
pnpm test      # vitest with coverage

After changing a rule's docs or meta, run pnpm update:eslint-docs to regenerate the docs (CI also regenerates them on PRs).

Add a changeset to a PR that should appear in the release notes in CHANGELOG.md (CI does not require it):

pnpm changeset          # choose major / minor / patch and write the summary
pnpm changeset --empty  # for a PR that should not appear in the release notes

Release

The JavaScript sources are published as they are. Only the type declarations are built: pnpm pack runs prepack, which runs build-types (removes old *.d.ts, then tsc -p build.tsconfig.json emits index.d.ts and lib/**/*.d.ts). The published files are listed in files of package.json.

  1. Apply the changesets: this bumps version in package.json, writes the ## x.y.z section of CHANGELOG.md and deletes the used changesets. Review and commit the result.

    pnpm changeset version
  2. Check that everything passes:

    pnpm install --frozen-lockfile
    pnpm lint
    pnpm test
  3. Build the package and check its contents:

    pnpm pack
    tar -tzf ysknsid25-eslint-plugin-react-x.y.z.tgz
  4. Stage the tarball on npm (staged publishing). Staging does not ask for 2FA.

    pnpm stage publish ysknsid25-eslint-plugin-react-x.y.z.tgz --access public
  5. Check the staged package, then approve it (asks for 2FA). This publishes it to npm.

    pnpm stage list @ysknsid25/eslint-plugin-react
    pnpm stage view <stage-id>
    pnpm stage approve <stage-id>
  6. Push the tag. The Release workflow creates a GitHub Release from the CHANGELOG.md section of that version.

    git tag vx.y.z
    git push origin vx.y.z

License

Licensed under the MIT License. Copyright (c) 2014 Yannick Croissant (original eslint-plugin-react), Copyright (c) 2026 Kanon (this fork).

About

Fork from `jsx-eslint/eslint-plugin-react`. Main propose is maintaining dependencie updates. React-specific linting rules for ESLint

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages