@wistia/eslint-config 2.3.1 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
- // only add react rules
2
- // see: https://github.com/jsx-eslint/eslint-plugin-react#list-of-supported-rules
1
+ // @eslint-react rules
2
+ // see: https://beta.eslint-react.xyz/docs/rules
3
3
 
4
4
  export default {
5
5
  // Enforce that class methods utilize this
@@ -28,570 +28,291 @@ export default {
28
28
  },
29
29
  ],
30
30
 
31
- // Surfaces problematic React code found by the React compiler
32
- 'react-compiler/react-compiler': 'error',
31
+ // --- Core React rules ---
33
32
 
34
- // Prevent missing displayName in a React component definition
35
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/display-name.md
36
- 'react/display-name': ['off', { ignoreTranspilerName: false }],
33
+ // Validates higher order functions defining nested components or hooks
34
+ '@eslint-react/component-hook-factories': 'error',
37
35
 
38
- // Forbid certain propTypes (any, array, object)
39
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-prop-types.md
40
- // decision: prop-types are deprecated in favor of TypeScript types
41
- 'react/forbid-prop-types': 'off',
36
+ // Validates usage of Error Boundaries instead of try/catch for child errors
37
+ '@eslint-react/error-boundaries': 'error',
42
38
 
43
- // Forbid certain props on DOM Nodes
44
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-dom-props.md
45
- 'react/forbid-dom-props': ['off', { forbid: [] }],
39
+ // Verify the list of the dependencies for Hooks like useEffect and similar
40
+ '@eslint-react/exhaustive-deps': 'error',
46
41
 
47
- // Enforce boolean attributes notation in JSX; enable for consistency
48
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md
49
- 'react/jsx-boolean-value': ['error', 'always'],
42
+ // Validates against mutating props, state, and other immutable values
43
+ '@eslint-react/immutability': 'error',
50
44
 
51
- // Validate closing bracket location in JSX
52
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md
53
- // decision: disabled because this is a formatter concern
54
- 'react/jsx-closing-bracket-location': 'off',
45
+ // Prevents unintentional '$' sign before expression in JSX
46
+ '@eslint-react/jsx-dollar': 'error',
55
47
 
56
- // Validate closing tag location in JSX
57
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-tag-location.md
58
- // decision: disabled because this is a formatter concern
59
- 'react/jsx-closing-tag-location': 'off',
48
+ // Enforce key prop comes before spread to avoid overriding
49
+ '@eslint-react/jsx-key-before-spread': 'error',
60
50
 
61
- // Enforce or disallow spaces inside of curly braces in JSX attributes
62
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-spacing.md
63
- // decision: disabled because this is a formatter concern
64
- 'react/jsx-curly-spacing': 'off',
51
+ // Prevent accidental JS comments from being injected into JSX as text
52
+ '@eslint-react/jsx-no-comment-textnodes': 'error',
65
53
 
66
- // Enforce event handler naming conventions in JSX
67
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-handler-names.md
68
- 'react/jsx-handler-names': [
69
- 'error',
70
- {
71
- eventHandlerPrefix: 'handle',
72
- eventHandlerPropPrefix: 'on',
73
- checkLocalVariables: true,
74
- checkInlineFunction: false,
75
- },
76
- ],
54
+ // Enforce explicit boolean prop syntax (e.g. disabled={true} instead of disabled)
55
+ // note: -1 means "never use shorthand" (equivalent to react/jsx-boolean-value: ['error', 'always'])
56
+ '@eslint-react/jsx-shorthand-boolean': ['error', -1],
77
57
 
78
- // Validate props indentation in JSX
79
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-indent-props.md
80
- // decision: disabled because this is a formatter concern
81
- 'react/jsx-indent-props': 'off',
58
+ // Enforce shorthand fragment syntax (<> instead of <React.Fragment>)
59
+ // note: 1 means "always use shorthand" (equivalent to react/jsx-fragments: ['error', 'syntax'])
60
+ '@eslint-react/jsx-shorthand-fragment': ['error', 1],
82
61
 
83
- // Validate JSX has key prop when in array or iterator
84
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-key.md
85
- 'react/jsx-key': [
86
- 'error',
87
- { checkFragmentShorthand: true, checkKeyMustBeforeSpread: true, warnOnDuplicates: true },
88
- ],
62
+ // Prevent using this.state within a this.setState
63
+ '@eslint-react/no-access-state-in-setstate': 'error',
89
64
 
90
- // Limit maximum of props on a single line in JSX
91
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-max-props-per-line.md
92
- // decision: disabled because this is a formatter concern
93
- 'react/jsx-max-props-per-line': 'off',
65
+ // Prevent usage of Array index in keys
66
+ '@eslint-react/no-array-index-key': 'error',
94
67
 
95
- // Prevent usage of .bind() in JSX props
96
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md
97
- 'react/jsx-no-bind': [
98
- 'error',
99
- {
100
- ignoreRefs: true,
101
- allowArrowFunctions: true,
102
- allowFunctions: false,
103
- allowBind: false,
104
- ignoreDOMComponents: true,
105
- },
106
- ],
68
+ // Disallow usage of Children.count
69
+ '@eslint-react/no-children-count': 'error',
107
70
 
108
- // Prevent duplicate props in JSX
109
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-duplicate-props.md
110
- 'react/jsx-no-duplicate-props': ['error', { ignoreCase: true }],
71
+ // Disallow usage of Children.forEach
72
+ '@eslint-react/no-children-for-each': 'error',
111
73
 
112
- // Prevent usage of unwrapped JSX strings
113
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-literals.md
114
- 'react/jsx-no-literals': ['off', { noStrings: true }],
74
+ // Disallow usage of Children.map
75
+ '@eslint-react/no-children-map': 'error',
115
76
 
116
- // Disallow undeclared variables in JSX
117
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-undef.md
118
- 'react/jsx-no-undef': 'error',
77
+ // Disallow usage of Children.only
78
+ '@eslint-react/no-children-only': 'error',
119
79
 
120
- // Enforce PascalCase for user-defined JSX components
121
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md
122
- 'react/jsx-pascal-case': [
123
- 'error',
124
- {
125
- allowAllCaps: true,
126
- ignore: [],
127
- },
128
- ],
80
+ // Prevent passing of children as props
81
+ '@eslint-react/no-children-prop': 'error',
129
82
 
130
- // Enforce propTypes declarations alphabetical sorting
131
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/sort-prop-types.md
132
- // decision: prop-types are deprecated in favor of TypeScript types
133
- 'react/sort-prop-types': 'off',
83
+ // Disallow usage of Children.toArray
84
+ '@eslint-react/no-children-to-array': 'error',
134
85
 
135
- // Deprecated in favor of react/jsx-sort-props
136
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-sort-prop-types.md
137
- 'react/jsx-sort-prop-types': 'off',
86
+ // Disallow class components (except for error boundaries)
87
+ '@eslint-react/no-class-component': 'error',
138
88
 
139
- // Enforce props alphabetical sorting
140
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-sort-props.md
141
- 'react/jsx-sort-props': [
142
- 'error',
143
- {
144
- ignoreCase: true,
145
- callbacksLast: false,
146
- shorthandFirst: false,
147
- shorthandLast: false,
148
- noSortAlphabetically: false,
149
- reservedFirst: true,
150
- },
151
- ],
89
+ // Disallow usage of cloneElement
90
+ '@eslint-react/no-clone-element': 'error',
152
91
 
153
- // Prevent React to be incorrectly marked as unused
154
- // decision: no longer required with React >= 17
155
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-uses-react.md
156
- 'react/jsx-uses-react': 'off',
92
+ // Disallow usage of componentWillMount
93
+ '@eslint-react/no-component-will-mount': 'error',
157
94
 
158
- // Prevent variables used in JSX to be incorrectly marked as unused
159
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-uses-vars.md
160
- 'react/jsx-uses-vars': 'error',
95
+ // Disallow usage of componentWillReceiveProps
96
+ '@eslint-react/no-component-will-receive-props': 'error',
161
97
 
162
- // Prevent usage of dangerous JSX properties
163
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-danger.md
164
- 'react/no-danger': 'error',
98
+ // Disallow usage of componentWillUpdate
99
+ '@eslint-react/no-component-will-update': 'error',
165
100
 
166
- // Prevent usage of deprecated methods
167
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-deprecated.md
168
- 'react/no-deprecated': 'error',
101
+ // Disallow usage of legacy Context.Provider (React 19+)
102
+ '@eslint-react/no-context-provider': 'error',
169
103
 
170
- // Prevent usage of setState in componentDidMount
171
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-did-mount-set-state.md
172
- // this is necessary for server-rendering
173
- 'react/no-did-mount-set-state': 'error',
104
+ // Disallow usage of createRef (prefer useRef)
105
+ '@eslint-react/no-create-ref': 'error',
174
106
 
175
- // Prevent usage of setState in componentDidUpdate
176
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-did-update-set-state.md
177
- 'react/no-did-update-set-state': 'error',
107
+ // Prevent direct mutation of this.state
108
+ '@eslint-react/no-direct-mutation-state': 'error',
178
109
 
179
- // Prevent usage of setState in componentWillUpdate
180
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-will-update-set-state.md
181
- 'react/no-will-update-set-state': 'error',
110
+ // Disallow duplicate keys in JSX arrays
111
+ '@eslint-react/no-duplicate-key': 'error',
182
112
 
183
- // Prevent direct mutation of this.state
184
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-direct-mutation-state.md
185
- 'react/no-direct-mutation-state': 'off',
113
+ // Disallow usage of forwardRef (React 19+ passes ref as prop)
114
+ '@eslint-react/no-forward-ref': 'error',
186
115
 
187
- // Prevent usage of isMounted
188
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-is-mounted.md
189
- 'react/no-is-mounted': 'error',
116
+ // Prevent implicitly passing the children prop
117
+ '@eslint-react/no-implicit-children': 'error',
190
118
 
191
- // Prevent multiple component definition per file
192
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md
193
- 'react/no-multi-comp': 'off',
119
+ // Prevent implicitly passing the key prop
120
+ '@eslint-react/no-implicit-key': 'error',
194
121
 
195
- // Prevent usage of setState
196
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-set-state.md
197
- 'react/no-set-state': 'off',
122
+ // Prevent implicitly passing the ref prop
123
+ '@eslint-react/no-implicit-ref': 'error',
198
124
 
199
- // Prevent using string references
200
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-string-refs.md
201
- 'react/no-string-refs': 'error',
125
+ // Prevent problematic leaked values from being rendered
126
+ '@eslint-react/no-leaked-conditional-rendering': 'error',
202
127
 
203
- // Prevent usage of unknown DOM property
204
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unknown-property.md
205
- 'react/no-unknown-property': 'error',
206
-
207
- // Require ES6 class declarations over React.createClass
208
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-es6-class.md
209
- 'react/prefer-es6-class': ['error', 'always'],
210
-
211
- // Require stateless functions when not using lifecycle methods, setState or ref
212
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md
213
- 'react/prefer-stateless-function': ['error', { ignorePureComponents: true }],
214
-
215
- // Prevent missing props validation in a React component definition
216
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prop-types.md
217
- // decision: prop-types are deprecated in favor of TypeScript types
218
- 'react/prop-types': 'off',
219
-
220
- // Prevent missing React when using JSX
221
- // decision: no longer required with React 17 & babel `automatic` runtime
222
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/react-in-jsx-scope.md
223
- 'react/react-in-jsx-scope': 'off',
224
-
225
- // Require render() methods to return something
226
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/require-render-return.md
227
- 'react/require-render-return': 'error',
228
-
229
- // Prevent extra closing tags for components without children
230
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md
231
- 'react/self-closing-comp': 'error',
232
-
233
- // Enforce component methods order
234
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/sort-comp.md
235
- 'react/sort-comp': [
236
- 'error',
237
- {
238
- order: [
239
- 'static-variables',
240
- 'static-methods',
241
- 'instance-variables',
242
- 'lifecycle',
243
- '/^handle.+$/',
244
- '/^on.+$/',
245
- 'getters',
246
- 'setters',
247
- '/^(get|set)(?!(InitialState$|DefaultProps$|ChildContext$)).+$/',
248
- 'instance-methods',
249
- 'everything-else',
250
- 'rendering',
251
- ],
252
- groups: {
253
- lifecycle: [
254
- 'displayName',
255
- 'propTypes',
256
- 'contextTypes',
257
- 'childContextTypes',
258
- 'mixins',
259
- 'statics',
260
- 'defaultProps',
261
- 'constructor',
262
- 'getDefaultProps',
263
- 'getInitialState',
264
- 'state',
265
- 'getChildContext',
266
- 'getDerivedStateFromProps',
267
- 'componentWillMount',
268
- 'UNSAFE_componentWillMount',
269
- 'componentDidMount',
270
- 'componentWillReceiveProps',
271
- 'UNSAFE_componentWillReceiveProps',
272
- 'shouldComponentUpdate',
273
- 'componentWillUpdate',
274
- 'UNSAFE_componentWillUpdate',
275
- 'getSnapshotBeforeUpdate',
276
- 'componentDidUpdate',
277
- 'componentDidCatch',
278
- 'componentWillUnmount',
279
- ],
280
- rendering: ['/^render.+$/', 'render'],
281
- },
282
- },
283
- ],
128
+ // Enforce that components have a displayName for DevTools
129
+ '@eslint-react/no-missing-component-display-name': 'off',
284
130
 
285
- // Enforce defaultProps declarations alphabetical sorting
286
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/sort-default-props.md
287
- 'react/sort-default-props': [
288
- 'error',
289
- {
290
- ignoreCase: true,
291
- },
292
- ],
131
+ // Enforce that contexts have a displayName for DevTools
132
+ '@eslint-react/no-missing-context-display-name': 'off',
133
+
134
+ // Enforce that every JSX element in a list has a key prop
135
+ '@eslint-react/no-missing-key': 'error',
136
+
137
+ // Disallow misusing captureOwnerStack
138
+ '@eslint-react/no-misused-capture-owner-stack': 'error',
139
+
140
+ // Prevent creating unstable components inside components
141
+ '@eslint-react/no-nested-component-definitions': 'error',
293
142
 
294
- // Prevent missing parentheses around multilines JSX
295
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-wrap-multilines.md
296
- // decision: disabled because this is a formatter concern
297
- 'react/jsx-wrap-multilines': 'off',
143
+ // Prevent creating lazy components inside components
144
+ '@eslint-react/no-nested-lazy-component-declarations': 'error',
298
145
 
299
- // Require that the first prop in a JSX element be on a new line when the element is multiline
300
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-first-prop-new-line.md
301
- // decision: disabled because this is a formatter concern
302
- 'react/jsx-first-prop-new-line': 'off',
146
+ // Prevent usage of shouldComponentUpdate when extending React.PureComponent
147
+ '@eslint-react/no-redundant-should-component-update': 'error',
303
148
 
304
- // Enforce spacing around jsx equals signs
305
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-equals-spacing.md
306
- // decision: disabled because this is a formatter concern
307
- 'react/jsx-equals-spacing': 'off',
149
+ // Prevent usage of setState in componentDidMount
150
+ '@eslint-react/no-set-state-in-component-did-mount': 'error',
308
151
 
309
- // Enforce JSX indentation
310
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-indent.md
311
- // decision: disabled because this is a formatter concern
312
- 'react/jsx-indent': 'off',
152
+ // Prevent usage of setState in componentDidUpdate
153
+ '@eslint-react/no-set-state-in-component-did-update': 'error',
313
154
 
314
- // Disallow target="_blank" on links
315
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-target-blank.md
316
- 'react/jsx-no-target-blank': ['error', { enforceDynamicLinks: 'always' }],
155
+ // Prevent usage of setState in componentWillUpdate
156
+ '@eslint-react/no-set-state-in-component-will-update': 'error',
317
157
 
318
- // only .jsx & .tsx files may have JSX
319
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md
320
- // decision: include typescript extensions to allow interop
321
- 'react/jsx-filename-extension': ['error', { extensions: ['.jsx', '.tsx'] }],
158
+ // Disallow unnecessary useCallback hooks
159
+ '@eslint-react/no-unnecessary-use-callback': 'error',
322
160
 
323
- // prevent accidental JS comments from being injected into JSX as text
324
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-comment-textnodes.md
325
- 'react/jsx-no-comment-textnodes': 'error',
161
+ // Disallow unnecessary useMemo hooks
162
+ '@eslint-react/no-unnecessary-use-memo': 'error',
326
163
 
327
- // disallow using React.render/ReactDOM.render's return value
328
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-render-return-value.md
329
- 'react/no-render-return-value': 'error',
164
+ // Disallow unnecessary "use" prefix on custom hooks
165
+ '@eslint-react/no-unnecessary-use-prefix': 'error',
330
166
 
331
- // require a shouldComponentUpdate method, or PureRenderMixin
332
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/require-optimization.md
333
- 'react/require-optimization': ['off', { allowDecorators: [] }],
167
+ // Disallow usage of UNSAFE_componentWillMount
168
+ '@eslint-react/no-unsafe-component-will-mount': 'error',
334
169
 
335
- // warn against using findDOMNode()
336
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-find-dom-node.md
337
- 'react/no-find-dom-node': 'error',
170
+ // Disallow usage of UNSAFE_componentWillReceiveProps
171
+ '@eslint-react/no-unsafe-component-will-receive-props': 'error',
338
172
 
339
- // Forbid certain props on Components
340
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-component-props.md
341
- 'react/forbid-component-props': ['off', { forbid: [] }],
173
+ // Disallow usage of UNSAFE_componentWillUpdate
174
+ '@eslint-react/no-unsafe-component-will-update': 'error',
342
175
 
343
- // Forbid certain elements
344
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-elements.md
345
- 'react/forbid-elements': ['off', { forbid: [] }],
176
+ // Prevent non-stable values used as context values
177
+ '@eslint-react/no-unstable-context-value': 'error',
346
178
 
347
- // Prevent problem with children and props.dangerouslySetInnerHTML
348
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-danger-with-children.md
349
- 'react/no-danger-with-children': 'error',
179
+ // Disallow referential-type variables as default props
180
+ '@eslint-react/no-unstable-default-props': 'error',
350
181
 
351
- // Prevent unused propType definitions
352
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unused-prop-types.md
353
- // decision: prop-types are deprecated in favor of TypeScript types
354
- 'react/no-unused-prop-types': 'off',
182
+ // Prevent declaring unused methods of component class
183
+ '@eslint-react/no-unused-class-component-members': 'error',
355
184
 
356
- // Require style prop value be an object or var
357
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/style-prop-object.md
358
- 'react/style-prop-object': 'error',
185
+ // Warn about component props that are defined but never used
186
+ '@eslint-react/no-unused-props': 'error',
359
187
 
360
- // Prevent invalid characters from appearing in markup
361
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unescaped-entities.md
362
- 'react/no-unescaped-entities': 'error',
188
+ // Prevent unused state values
189
+ '@eslint-react/no-unused-state': 'error',
363
190
 
364
- // Prevent passing of children as props
365
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-children-prop.md
366
- 'react/no-children-prop': 'error',
191
+ // Prefer using use() over useContext() (React 19+)
192
+ '@eslint-react/no-use-context': 'error',
367
193
 
368
- // Validate whitespace in and around the JSX opening and closing brackets
369
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-tag-spacing.md
370
- // decision: disabled because this is a formatter concern
371
- 'react/jsx-tag-spacing': 'off',
194
+ // Disallow unnecessary fragments
195
+ '@eslint-react/no-useless-fragment': 'error',
372
196
 
373
- // Enforce spaces before the closing bracket of self-closing JSX elements
374
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-space-before-closing.md
375
- // decision: this rule is deprecated. It was replaced by react/jsx-tag-spacing.
376
- // 'react/jsx-space-before-closing': 'off',
197
+ // Enforce consistent usage of destructuring assignment of props, state, and context
198
+ '@eslint-react/prefer-destructuring-assignment': 'off',
377
199
 
378
- // Prevent usage of Array index in keys
379
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-array-index-key.md
380
- 'react/no-array-index-key': 'error',
200
+ // Enforce importing React via a namespace import
201
+ '@eslint-react/prefer-namespace-import': 'off',
381
202
 
382
- // Enforce a defaultProps definition for every prop that is not a required prop
383
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/require-default-props.md
384
- // decision: default prop types shouldn't be necessary for optional parameters as they can just default to undefined
385
- 'react/require-default-props': 'off',
203
+ // Validates that components/hooks are pure
204
+ '@eslint-react/purity': 'error',
386
205
 
387
- // Forbids using non-exported propTypes
388
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-foreign-prop-types.md
389
- // decision: prop-types are deprecated in favor of TypeScript types
390
- 'react/forbid-foreign-prop-types': 'off',
206
+ // Validates correct usage of refs, not reading/writing during render
207
+ '@eslint-react/refs': 'error',
391
208
 
392
- // Prevent void DOM elements from receiving children
393
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/void-dom-elements-no-children.md
394
- 'react/void-dom-elements-no-children': 'error',
209
+ // Enforce Rules of Hooks
210
+ '@eslint-react/rules-of-hooks': 'error',
395
211
 
396
- // Enforce all defaultProps have a corresponding non-required PropType
397
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/default-props-match-prop-types.md
398
- // decision: prop-types are deprecated in favor of TypeScript types
399
- 'react/default-props-match-prop-types': 'off',
212
+ // Validates against calling setState synchronously in an effect
213
+ '@eslint-react/set-state-in-effect': 'error',
400
214
 
401
- // Prevent usage of shouldComponentUpdate when extending React.PureComponent
402
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-redundant-should-component-update.md
403
- 'react/no-redundant-should-component-update': 'error',
215
+ // Validates against setting state during render
216
+ '@eslint-react/set-state-in-render': 'error',
404
217
 
405
- // Prevent unused state values
406
- // https://github.com/jsx-eslint/eslint-plugin-react/pull/1103/
407
- 'react/no-unused-state': 'error',
218
+ // Enforces the Rules of Props (unstable)
219
+ '@eslint-react/unstable-rules-of-props': 'error',
408
220
 
409
- // Enforces consistent naming for boolean props
410
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/boolean-prop-naming.md
411
- 'react/boolean-prop-naming': [
412
- 'off',
413
- {
414
- propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],
415
- rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+',
416
- message: '',
417
- },
418
- ],
221
+ // Enforces the Rules of State (unstable)
222
+ '@eslint-react/unstable-rules-of-state': 'error',
419
223
 
420
- // Prevents common casing typos
421
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-typos.md
422
- 'react/no-typos': 'error',
224
+ // Validates against syntax that React does not support
225
+ '@eslint-react/unsupported-syntax': 'error',
423
226
 
424
- // Enforce curly braces or disallow unnecessary curly braces in JSX props and/or children
425
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-brace-presence.md
426
- 'react/jsx-curly-brace-presence': ['error', { props: 'never', children: 'never' }],
227
+ // Validates usage of useMemo with a return value
228
+ '@eslint-react/use-memo': 'error',
427
229
 
428
- // One JSX Element Per Line
429
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-one-expression-per-line.md
430
- // decision: disabled because this is a formatter concern
431
- 'react/jsx-one-expression-per-line': 'off',
230
+ // Ensure destructuring and symmetric naming of useState hook value and setter
231
+ '@eslint-react/use-state': 'error',
432
232
 
433
- // Enforce consistent usage of destructuring assignment of props, state, and context
434
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/destructuring-assignment.md
435
- // decision: it's acceptable to mix these even at the expense of consistency
436
- 'react/destructuring-assignment': ['off', 'always'],
233
+ // --- React DOM rules ---
437
234
 
438
- // Prevent using this.state within a this.setState
439
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-access-state-in-setstate.md
440
- 'react/no-access-state-in-setstate': 'error',
235
+ // Warn on usage of dangerouslySetInnerHTML
236
+ '@eslint-react/dom/no-dangerously-set-innerhtml': 'error',
441
237
 
442
- // Prevent usage of button elements without an explicit type attribute
443
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/button-has-type.md
444
- 'react/button-has-type': [
445
- 'error',
446
- {
447
- button: true,
448
- submit: true,
449
- reset: false,
450
- },
451
- ],
238
+ // Prevent problem with children and dangerouslySetInnerHTML
239
+ '@eslint-react/dom/no-dangerously-set-innerhtml-with-children': 'error',
452
240
 
453
- // Ensures inline tags are not rendered without spaces between them
454
- 'react/jsx-child-element-spacing': 'off',
241
+ // Warn against using findDOMNode()
242
+ '@eslint-react/dom/no-find-dom-node': 'error',
455
243
 
456
- // Prevent this from being used in stateless functional components
457
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-this-in-sfc.md
458
- 'react/no-this-in-sfc': 'error',
244
+ // Disallow usage of flushSync
245
+ '@eslint-react/dom/no-flush-sync': 'error',
459
246
 
460
- // Validate JSX maximum depth
461
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-max-depth.md
462
- 'react/jsx-max-depth': 'off',
247
+ // Disallow usage of ReactDOM.hydrate (use hydrateRoot instead)
248
+ '@eslint-react/dom/no-hydrate': 'error',
463
249
 
464
- // Disallow multiple spaces between inline JSX props
465
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-multi-spaces.md
466
- 'react/jsx-props-no-multi-spaces': 'off',
250
+ // Enforce that buttons have an explicit type attribute
251
+ '@eslint-react/dom/no-missing-button-type': 'error',
467
252
 
468
- // Prevent usage of UNSAFE_ methods
469
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unsafe.md
470
- 'react/no-unsafe': 'off',
253
+ // Enforce sandbox attribute on iframe elements
254
+ '@eslint-react/dom/no-missing-iframe-sandbox': 'error',
471
255
 
472
- // Enforce shorthand or standard form for React fragments
473
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-fragments.md
474
- 'react/jsx-fragments': ['error', 'syntax'],
256
+ // Enforce that namespaces are not used in React elements
257
+ '@eslint-react/dom/no-namespace': 'error',
475
258
 
476
- // Enforce linebreaks in curly braces in JSX attributes and expressions.
477
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-newline.md
478
- // decision: disabled because this is a formatter concern
479
- 'react/jsx-curly-newline': 'off',
259
+ // Disallow usage of ReactDOM.render (use createRoot instead)
260
+ '@eslint-react/dom/no-render': 'error',
480
261
 
481
- // Enforce state initialization style
482
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/state-in-constructor.md
483
- 'react/state-in-constructor': ['error', 'never'],
262
+ // Disallow using ReactDOM.render return value
263
+ '@eslint-react/dom/no-render-return-value': 'error',
484
264
 
485
- // Enforces where React component static properties should be positioned
486
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/static-property-placement.md
487
- 'react/static-property-placement': ['error', 'static public field'],
265
+ // Prevent usage of javascript: URLs
266
+ '@eslint-react/dom/no-script-url': 'error',
488
267
 
489
- // Disallow JSX props spreading
490
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-spreading.md
491
- // decision: because we have type safety in TypeScript, this rule isn't necessary as we will see
492
- // TS errors for prop spreading against mismatched (prop)type declarations
493
- 'react/jsx-props-no-spreading': 'off',
268
+ // Require style prop value be an object
269
+ '@eslint-react/dom/no-string-style-prop': 'error',
494
270
 
495
- // Enforce that props are read-only
496
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-read-only-props.md
497
- 'react/prefer-read-only-props': 'off',
271
+ // Prevent usage of unknown DOM property
272
+ '@eslint-react/dom/no-unknown-property': 'error',
498
273
 
499
- // Prevent usage of `javascript:` URLs
500
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-script-url.md
501
- 'react/jsx-no-script-url': [
502
- 'error',
503
- [
504
- {
505
- name: 'Link',
506
- props: ['to'],
507
- },
508
- ],
509
- ],
274
+ // Enforce safe iframe sandbox attribute values
275
+ '@eslint-react/dom/no-unsafe-iframe-sandbox': 'error',
510
276
 
511
- // Disallow unnecessary fragments
512
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-useless-fragment.md
513
- 'react/jsx-no-useless-fragment': 'error',
277
+ // Disallow target="_blank" without rel="noreferrer"
278
+ '@eslint-react/dom/no-unsafe-target-blank': 'error',
514
279
 
515
- // Prevent adjacent inline elements not separated by whitespace
516
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-adjacent-inline-elements.md
517
- 'react/no-adjacent-inline-elements': 'error',
280
+ // Disallow usage of deprecated useFormState (use useActionState instead)
281
+ '@eslint-react/dom/no-use-form-state': 'error',
518
282
 
519
- // Enforce a specific function type for function components
520
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/function-component-definition.md
521
- 'react/function-component-definition': [
522
- 'error',
523
- {
524
- namedComponents: 'arrow-function',
525
- unnamedComponents: 'arrow-function',
526
- },
527
- ],
283
+ // Prevent void DOM elements from receiving children
284
+ '@eslint-react/dom/no-void-elements-with-children': 'error',
528
285
 
529
- // Enforce a new line after jsx elements and expressions
530
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-newline.md
531
- // decision: disabled because this is a formatter concern
532
- 'react/jsx-newline': 'off',
286
+ // Enforce importing React DOM via a namespace import
287
+ '@eslint-react/dom/prefer-namespace-import': 'off',
533
288
 
534
- // Prevent react contexts from taking non-stable values
535
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-constructed-context-values.md
536
- 'react/jsx-no-constructed-context-values': 'error',
289
+ // --- RSC rules ---
537
290
 
538
- // Prevent creating unstable components inside components
539
- // decision: adjusted to allow for render props
540
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unstable-nested-components.md
541
- 'react/no-unstable-nested-components': ['error', { allowAsProps: true }],
291
+ // Enforce correct function definition for React Server Components
292
+ '@eslint-react/rsc/function-definition': 'error',
542
293
 
543
- // Enforce that namespaces are not used in React elements
544
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-namespace.md
545
- 'react/no-namespace': 'error',
294
+ // --- Naming convention rules ---
546
295
 
547
- // Prefer exact proptype definitions
548
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-exact-props.md
549
- 'react/prefer-exact-props': 'error',
296
+ // Enforce consistent naming for React context
297
+ '@eslint-react/naming-convention/context-name': 'error',
550
298
 
551
- // Lifecycle methods should be methods on the prototype, not class fields
552
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-arrow-function-lifecycle.md
553
- 'react/no-arrow-function-lifecycle': 'error',
299
+ // Enforce consistent naming for React component identifiers
300
+ '@eslint-react/naming-convention/id-name': 'error',
554
301
 
555
- // Prevent usage of invalid attributes
556
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-invalid-html-attribute.md
557
- 'react/no-invalid-html-attribute': 'error',
302
+ // Enforce consistent naming for refs
303
+ '@eslint-react/naming-convention/ref-name': 'error',
558
304
 
559
- // Prevent declaring unused methods of component class
560
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unused-class-component-methods.md
561
- 'react/no-unused-class-component-methods': 'error',
305
+ // --- Web API rules ---
562
306
 
563
- // Ensure destructuring and symmetric naming of useState hook value and setter variables
564
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/hook-use-state.md
565
- 'react/hook-use-state': 'error',
307
+ // Prevent leaked event listeners
308
+ '@eslint-react/web-api/no-leaked-event-listener': 'error',
566
309
 
567
- // Enforce sandbox attribute on iframe elements
568
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/iframe-missing-sandbox.md
569
- 'react/iframe-missing-sandbox': 'error',
310
+ // Prevent leaked setInterval calls
311
+ '@eslint-react/web-api/no-leaked-interval': 'error',
570
312
 
571
- // Prevent problematic leaked values from being rendered
572
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-leaked-render.md
573
- 'react/jsx-no-leaked-render': 'error',
574
-
575
- // Enforce using `onChange` or `readonly` attribute when `checked` is used
576
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/checked-requires-onchange-or-readonly.md
577
- 'react/checked-requires-onchange-or-readonly': 'error',
578
-
579
- // Disallow usage of referential-type variables as default param in functional component
580
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-object-type-as-default-prop.md
581
- // decision: there's an edge case issue this could prevent but it's not common enough to warrant the rule
582
- 'react/no-object-type-as-default-prop': 'off',
583
-
584
- // Some developers prefer to sort defaultProps declarations alphabetically to be able to find necessary declarations easier at a later time.
585
- // Others feel that it adds complexity and becomes a burden to maintain.
586
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-sort-default-props.md
587
- // decision: this rule is deprecated. It was replaced by `react/sort-default-props`
588
- // 'react/jsx-sort-default-props': 'off',
589
-
590
- // Require all forwardRef components include a ref parameter
591
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forward-ref-uses-ref.md
592
- 'react/forward-ref-uses-ref': 'error',
593
-
594
- // Disallow JSX prop spreading the same identifier multiple times
595
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-spread-multi.md
596
- 'react/jsx-props-no-spread-multi': 'error',
313
+ // Prevent leaked ResizeObserver instances
314
+ '@eslint-react/web-api/no-leaked-resize-observer': 'error',
315
+
316
+ // Prevent leaked setTimeout calls
317
+ '@eslint-react/web-api/no-leaked-timeout': 'error',
597
318
  };