@lumelabs/eslint-config 0.1.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.
package/LICENSE.md ADDED
@@ -0,0 +1,11 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2012 Airbnb
4
+
5
+ Copyright (c) 2026 Lumelabs
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # @lumelabs/eslint-config-react
2
+
3
+ > ⚠️ **Experimental / Internal Use Only**
4
+ >
5
+ > This configuration is primarily intended for personal and internal use.
6
+ > It may change, break, or be restructured at any time without notice.
7
+ >
8
+ > **Do not rely on this package for production or public projects unless you are prepared to maintain your own fork.**
9
+ >
10
+ > **Issues and feature requests may be closed without response.**
11
+
12
+ Opinionated ESLint configuration for **TypeScript + React** projects.
13
+
14
+ This preset is designed for modern setups using TypeScript, React, Vite/Webpack, and Prettier.
15
+ It prioritizes practical correctness over strict ideology and avoids rules that tend to create noise
16
+ or force unnatural code patterns.
17
+
18
+ ---
19
+
20
+ ## Features
21
+
22
+ - ESLint **8.x** only (fully bundled, no peer dependency juggling)
23
+ - TypeScript-first (no JS-only compromises)
24
+ - React + React Hooks + JSX a11y included
25
+ - Prettier-compatible
26
+ - Sensible defaults based on real-world usage, not theory
27
+ - No legacy or deprecated ESLint patterns
28
+
29
+ ---
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ npm install --save-dev @lumelabs/eslint-config-react
package/index.cjs ADDED
@@ -0,0 +1,59 @@
1
+ module.exports = {
2
+ extends: [
3
+ "eslint:recommended",
4
+
5
+ // TypeScript rules
6
+ require.resolve("./rules/typescript-eslint"),
7
+
8
+ // Base JS rules
9
+ require.resolve("./rules/best-practices"),
10
+ require.resolve("./rules/errors"),
11
+ require.resolve("./rules/node"),
12
+ require.resolve("./rules/style"),
13
+ require.resolve("./rules/variables"),
14
+ require.resolve("./rules/es6"),
15
+ require.resolve("./rules/imports"),
16
+ require.resolve("./rules/strict"),
17
+
18
+ // React rules
19
+ require.resolve("./rules/react"),
20
+ require.resolve("./rules/react-hooks"),
21
+ require.resolve("./rules/react-a11y"),
22
+
23
+ "prettier",
24
+
25
+ // Override. Use only if rules are not applied within "rules/*"
26
+ require.resolve("./override"),
27
+ ],
28
+
29
+ ignorePatterns: ["**/node_modules/**", "*.stories.*", "**/*.cjs"],
30
+ env: {
31
+ browser: true,
32
+ es2021: true,
33
+ node: true,
34
+ jest: true,
35
+ },
36
+ parser: "@typescript-eslint/parser",
37
+ parserOptions: {
38
+ ecmaFeatures: {
39
+ jsx: true,
40
+ },
41
+ ecmaVersion: "latest",
42
+ sourceType: "module",
43
+ },
44
+ rules: {
45
+ // Import
46
+ // "import-helpers/order-imports": "off",
47
+ // "import/no-cycle": "warn",
48
+ },
49
+ overrides: [
50
+ // Test files
51
+ {
52
+ files: ["**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts", "**/*.spec.tsx", "**/tests/**"],
53
+ rules: {
54
+ "import/no-extraneous-dependencies": "off",
55
+ "@typescript-eslint/no-explicit-any": "off",
56
+ },
57
+ },
58
+ ],
59
+ }
package/override.js ADDED
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ // Add here rules that somehow are not disabled when applied within "rules/*"
3
+ rules: {},
4
+ }
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@lumelabs/eslint-config",
3
+ "version": "0.1.0",
4
+ "description": "Opinionated ESLint configuration for TypeScript projects (both frontend and backend), based on ESLint 8.",
5
+ "license": "MIT",
6
+ "author": "Egor Arkhipov (Lumelabs)",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/lumine-labs/eslint-config"
10
+ },
11
+ "files": [
12
+ "index.cjs",
13
+ "override.js",
14
+ "rules",
15
+ "README.md",
16
+ "LICENSE.md"
17
+ ],
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "keywords": [
22
+ "eslint",
23
+ "eslint-config",
24
+ "typescript",
25
+ "eslint8",
26
+ "lint",
27
+ "code-style"
28
+ ],
29
+ "main": "index.cjs",
30
+ "exports": {
31
+ ".": "./index.cjs"
32
+ },
33
+ "dependencies": {
34
+ "@typescript-eslint/eslint-plugin": "^8.53.1",
35
+ "@typescript-eslint/parser": "^8.53.1",
36
+ "confusing-browser-globals": "^1.0.11",
37
+ "eslint": "^8.57.1",
38
+ "eslint-config-prettier": "^10.1.8",
39
+ "eslint-import-resolver-typescript": "^4.4.4",
40
+ "eslint-plugin-import": "^2.32.0",
41
+ "eslint-plugin-jsx-a11y": "^6.10.2",
42
+ "eslint-plugin-react": "^7.37.5",
43
+ "eslint-plugin-react-hooks": "^7.0.1"
44
+ },
45
+ "devDependencies": {
46
+ "prettier": "^3.8.1"
47
+ }
48
+ }
@@ -0,0 +1,431 @@
1
+ module.exports = {
2
+ rules: {
3
+ // enforces getter/setter pairs in objects
4
+ // https://eslint.org/docs/rules/accessor-pairs
5
+ "accessor-pairs": "off",
6
+
7
+ // enforces return statements in callbacks of array's methods
8
+ // https://eslint.org/docs/rules/array-callback-return
9
+ "array-callback-return": ["error", { allowImplicit: true }],
10
+
11
+ // treat var statements as if they were block scoped
12
+ // https://eslint.org/docs/rules/block-scoped-var
13
+ "block-scoped-var": "error",
14
+
15
+ // specify the maximum cyclomatic complexity allowed in a program
16
+ // https://eslint.org/docs/rules/complexity
17
+ complexity: ["off", 20],
18
+
19
+ // enforce that class methods use "this"
20
+ // https://eslint.org/docs/rules/class-methods-use-this
21
+ "class-methods-use-this": "off",
22
+
23
+ // require return statements to either always or never specify values
24
+ // https://eslint.org/docs/rules/consistent-return
25
+ "consistent-return": "off",
26
+
27
+ // specify curly brace conventions for all control statements
28
+ // https://eslint.org/docs/rules/curly
29
+ curly: ["error", "multi-line"], // multiline
30
+
31
+ // require default case in switch statements
32
+ // https://eslint.org/docs/rules/default-case
33
+ "default-case": ["warn", { commentPattern: "^no default$" }],
34
+
35
+ // Enforce default clauses in switch statements to be last
36
+ // https://eslint.org/docs/rules/default-case-last
37
+ "default-case-last": "error",
38
+
39
+ // https://eslint.org/docs/rules/default-param-last
40
+ "default-param-last": "error",
41
+
42
+ // encourages use of dot notation whenever possible
43
+ // https://eslint.org/docs/rules/dot-notation
44
+ "dot-notation": ["error", { allowKeywords: true }],
45
+
46
+ // enforces consistent newlines before or after dots
47
+ // https://eslint.org/docs/rules/dot-location
48
+ "dot-location": ["error", "property"],
49
+
50
+ // require the use of === and !==
51
+ // https://eslint.org/docs/rules/eqeqeq
52
+ eqeqeq: ["error", "always", { null: "ignore" }],
53
+
54
+ // Require grouped accessor pairs in object literals and classes
55
+ // https://eslint.org/docs/rules/grouped-accessor-pairs
56
+ "grouped-accessor-pairs": "error",
57
+
58
+ // make sure for-in loops have an if statement
59
+ // https://eslint.org/docs/rules/guard-for-in
60
+ "guard-for-in": "error",
61
+
62
+ // enforce a maximum number of classes per file
63
+ // https://eslint.org/docs/rules/max-classes-per-file
64
+ "max-classes-per-file": ["error", 1],
65
+
66
+ // disallow the use of alert, confirm, and prompt
67
+ // https://eslint.org/docs/rules/no-alert
68
+ // TODO: enable, semver-major
69
+ "no-alert": "warn",
70
+
71
+ // disallow use of arguments.caller or arguments.callee
72
+ // https://eslint.org/docs/rules/no-caller
73
+ "no-caller": "error",
74
+
75
+ // disallow lexical declarations in case/default clauses
76
+ // https://eslint.org/docs/rules/no-case-declarations
77
+ "no-case-declarations": "error",
78
+
79
+ // Disallow returning value in constructor
80
+ // https://eslint.org/docs/rules/no-constructor-return
81
+ "no-constructor-return": "error",
82
+
83
+ // disallow division operators explicitly at beginning of regular expression
84
+ // https://eslint.org/docs/rules/no-div-regex
85
+ "no-div-regex": "off",
86
+
87
+ // disallow else after a return in an if
88
+ // https://eslint.org/docs/rules/no-else-return
89
+ "no-else-return": ["error", { allowElseIf: false }],
90
+
91
+ // disallow empty functions, except for standalone funcs/arrows
92
+ // https://eslint.org/docs/rules/no-empty-function
93
+ "no-empty-function": "warn",
94
+
95
+ // disallow empty destructuring patterns
96
+ // https://eslint.org/docs/rules/no-empty-pattern
97
+ "no-empty-pattern": "warn",
98
+
99
+ // Disallow empty static blocks
100
+ // https://eslint.org/docs/latest/rules/no-empty-static-block
101
+ // TODO: semver-major, enable
102
+ "no-empty-static-block": "off",
103
+
104
+ // disallow comparisons to null without a type-checking operator
105
+ // https://eslint.org/docs/rules/no-eq-null
106
+ "no-eq-null": "off",
107
+
108
+ // disallow use of eval()
109
+ // https://eslint.org/docs/rules/no-eval
110
+ "no-eval": "error",
111
+
112
+ // disallow adding to native types
113
+ // https://eslint.org/docs/rules/no-extend-native
114
+ "no-extend-native": "error",
115
+
116
+ // disallow unnecessary function binding
117
+ // https://eslint.org/docs/rules/no-extra-bind
118
+ "no-extra-bind": "error",
119
+
120
+ // disallow Unnecessary Labels
121
+ // https://eslint.org/docs/rules/no-extra-label
122
+ "no-extra-label": "error",
123
+
124
+ // disallow fallthrough of case statements
125
+ // https://eslint.org/docs/rules/no-fallthrough
126
+ "no-fallthrough": "error",
127
+
128
+ // disallow the use of leading or trailing decimal points in numeric literals
129
+ // https://eslint.org/docs/rules/no-floating-decimal
130
+ "no-floating-decimal": "error",
131
+
132
+ // disallow reassignments of native objects or read-only globals
133
+ // https://eslint.org/docs/rules/no-global-assign
134
+ "no-global-assign": ["error", { exceptions: [] }],
135
+
136
+ // deprecated in favor of no-global-assign
137
+ // https://eslint.org/docs/rules/no-native-reassign
138
+ "no-native-reassign": "off",
139
+
140
+ // disallow implicit type conversions
141
+ // https://eslint.org/docs/rules/no-implicit-coercion
142
+ "no-implicit-coercion": [
143
+ "off",
144
+ {
145
+ boolean: false,
146
+ number: true,
147
+ string: true,
148
+ allow: [],
149
+ },
150
+ ],
151
+
152
+ // disallow var and named functions in global scope
153
+ // https://eslint.org/docs/rules/no-implicit-globals
154
+ "no-implicit-globals": "off",
155
+
156
+ // disallow use of eval()-like methods
157
+ // https://eslint.org/docs/rules/no-implied-eval
158
+ "no-implied-eval": "error",
159
+
160
+ // disallow this keywords outside of classes or class-like objects
161
+ // https://eslint.org/docs/rules/no-invalid-this
162
+ "no-invalid-this": "off",
163
+
164
+ // disallow usage of __iterator__ property
165
+ // https://eslint.org/docs/rules/no-iterator
166
+ "no-iterator": "error",
167
+
168
+ // disallow use of labels for anything other than loops and switches
169
+ // https://eslint.org/docs/rules/no-labels
170
+ "no-labels": ["error", { allowLoop: false, allowSwitch: false }],
171
+
172
+ // disallow unnecessary nested blocks
173
+ // https://eslint.org/docs/rules/no-lone-blocks
174
+ "no-lone-blocks": "error",
175
+
176
+ // disallow creation of functions within loops
177
+ // https://eslint.org/docs/rules/no-loop-func
178
+ "no-loop-func": "warn",
179
+
180
+ // disallow magic numbers
181
+ // https://eslint.org/docs/rules/no-magic-numbers
182
+ "no-magic-numbers": [
183
+ "off",
184
+ {
185
+ ignore: [],
186
+ ignoreArrayIndexes: true,
187
+ enforceConst: true,
188
+ detectObjects: false,
189
+ },
190
+ ],
191
+
192
+ // disallow use of multiple spaces
193
+ // https://eslint.org/docs/rules/no-multi-spaces
194
+ "no-multi-spaces": [
195
+ "error",
196
+ {
197
+ ignoreEOLComments: false,
198
+ },
199
+ ],
200
+
201
+ // disallow use of multiline strings
202
+ // https://eslint.org/docs/rules/no-multi-str
203
+ "no-multi-str": "error",
204
+
205
+ // disallow use of new operator when not part of the assignment or comparison
206
+ // https://eslint.org/docs/rules/no-new
207
+ "no-new": "error",
208
+
209
+ // disallow use of new operator for Function object
210
+ // https://eslint.org/docs/rules/no-new-func
211
+ "no-new-func": "error",
212
+
213
+ // disallows creating new instances of String, Number, and Boolean
214
+ // https://eslint.org/docs/rules/no-new-wrappers
215
+ "no-new-wrappers": "error",
216
+
217
+ // Disallow \8 and \9 escape sequences in string literals
218
+ // https://eslint.org/docs/rules/no-nonoctal-decimal-escape
219
+ "no-nonoctal-decimal-escape": "error",
220
+
221
+ // Disallow calls to the Object constructor without an argument
222
+ // https://eslint.org/docs/latest/rules/no-object-constructor
223
+ // TODO: enable, semver-major
224
+ "no-object-constructor": "off",
225
+
226
+ // disallow use of (old style) octal literals
227
+ // https://eslint.org/docs/rules/no-octal
228
+ "no-octal": "error",
229
+
230
+ // disallow use of octal escape sequences in string literals, such as
231
+ // var foo = 'Copyright \251';
232
+ // https://eslint.org/docs/rules/no-octal-escape
233
+ "no-octal-escape": "error",
234
+
235
+ // disallow reassignment of function parameters
236
+ // disallow parameter object manipulation except for specific exclusions
237
+ // rule: https://eslint.org/docs/rules/no-param-reassign.html
238
+ "no-param-reassign": "off",
239
+
240
+ // disallow usage of __proto__ property
241
+ // https://eslint.org/docs/rules/no-proto
242
+ "no-proto": "error",
243
+
244
+ // disallow declaring the same variable more than once
245
+ // https://eslint.org/docs/rules/no-redeclare
246
+ "no-redeclare": "warn",
247
+
248
+ // disallow certain object properties
249
+ // https://eslint.org/docs/rules/no-restricted-properties
250
+ "no-restricted-properties": [
251
+ "error",
252
+ {
253
+ object: "arguments",
254
+ property: "callee",
255
+ message: "arguments.callee is deprecated",
256
+ },
257
+ {
258
+ object: "global",
259
+ property: "isFinite",
260
+ message: "Please use Number.isFinite instead",
261
+ },
262
+ {
263
+ object: "self",
264
+ property: "isFinite",
265
+ message: "Please use Number.isFinite instead",
266
+ },
267
+ {
268
+ object: "window",
269
+ property: "isFinite",
270
+ message: "Please use Number.isFinite instead",
271
+ },
272
+ {
273
+ object: "global",
274
+ property: "isNaN",
275
+ message: "Please use Number.isNaN instead",
276
+ },
277
+ {
278
+ object: "self",
279
+ property: "isNaN",
280
+ message: "Please use Number.isNaN instead",
281
+ },
282
+ {
283
+ object: "window",
284
+ property: "isNaN",
285
+ message: "Please use Number.isNaN instead",
286
+ },
287
+ {
288
+ property: "__defineGetter__",
289
+ message: "Please use Object.defineProperty instead.",
290
+ },
291
+ {
292
+ property: "__defineSetter__",
293
+ message: "Please use Object.defineProperty instead.",
294
+ },
295
+ {
296
+ object: "Math",
297
+ property: "pow",
298
+ message: "Use the exponentiation operator (**) instead.",
299
+ },
300
+ ],
301
+
302
+ // disallow use of assignment in return statement
303
+ // https://eslint.org/docs/rules/no-return-assign
304
+ "no-return-assign": "off",
305
+
306
+ // disallow redundant `return await`
307
+ // https://eslint.org/docs/rules/no-return-await
308
+ "no-return-await": "error",
309
+
310
+ // disallow use of `javascript:` urls.
311
+ // https://eslint.org/docs/rules/no-script-url
312
+ "no-script-url": "error",
313
+
314
+ // disallow self assignment
315
+ // https://eslint.org/docs/rules/no-self-assign
316
+ "no-self-assign": [
317
+ "error",
318
+ {
319
+ props: true,
320
+ },
321
+ ],
322
+
323
+ // disallow comparisons where both sides are exactly the same
324
+ // https://eslint.org/docs/rules/no-self-compare
325
+ "no-self-compare": "error",
326
+
327
+ // disallow use of comma operator
328
+ // https://eslint.org/docs/rules/no-sequences
329
+ "no-sequences": "error",
330
+
331
+ // restrict what can be thrown as an exception
332
+ // https://eslint.org/docs/rules/no-throw-literal
333
+ "no-throw-literal": "error",
334
+
335
+ // disallow unmodified conditions of loops
336
+ // https://eslint.org/docs/rules/no-unmodified-loop-condition
337
+ "no-unmodified-loop-condition": "off",
338
+
339
+ // disallow usage of expressions in statement position
340
+ // https://eslint.org/docs/rules/no-unused-expressions
341
+ "no-unused-expressions": [
342
+ "error",
343
+ {
344
+ allowShortCircuit: false,
345
+ allowTernary: false,
346
+ allowTaggedTemplates: false,
347
+ },
348
+ ],
349
+
350
+ // disallow unused labels
351
+ // https://eslint.org/docs/rules/no-unused-labels
352
+ "no-unused-labels": "error",
353
+
354
+ // disallow unnecessary .call() and .apply()
355
+ // https://eslint.org/docs/rules/no-useless-call
356
+ "no-useless-call": "off",
357
+
358
+ // Disallow unnecessary catch clauses
359
+ // https://eslint.org/docs/rules/no-useless-catch
360
+ "no-useless-catch": "error",
361
+
362
+ // disallow useless string concatenation
363
+ // https://eslint.org/docs/rules/no-useless-concat
364
+ "no-useless-concat": "error",
365
+
366
+ // disallow unnecessary string escaping
367
+ // https://eslint.org/docs/rules/no-useless-escape
368
+ "no-useless-escape": "error",
369
+
370
+ // disallow redundant return; keywords
371
+ // https://eslint.org/docs/rules/no-useless-return
372
+ "no-useless-return": "warn",
373
+
374
+ // disallow use of void operator
375
+ // https://eslint.org/docs/rules/no-void
376
+ "no-void": "off",
377
+
378
+ // disallow usage of configurable warning terms in comments: e.g. todo
379
+ // https://eslint.org/docs/rules/no-warning-comments
380
+ "no-warning-comments": ["off", { terms: ["todo", "fixme", "xxx"], location: "start" }],
381
+
382
+ // disallow use of the with statement
383
+ // https://eslint.org/docs/rules/no-with
384
+ "no-with": "error",
385
+
386
+ // require using Error objects as Promise rejection reasons
387
+ // https://eslint.org/docs/rules/prefer-promise-reject-errors
388
+ "prefer-promise-reject-errors": ["error", { allowEmptyReject: true }],
389
+
390
+ // Suggest using named capture group in regular expression
391
+ // https://eslint.org/docs/rules/prefer-named-capture-group
392
+ "prefer-named-capture-group": "off",
393
+
394
+ // Prefer Object.hasOwn() over Object.prototype.hasOwnProperty.call()
395
+ // https://eslint.org/docs/rules/prefer-object-has-own
396
+ // TODO: semver-major: enable thus rule, once eslint v8.5.0 is required
397
+ "prefer-object-has-own": "off",
398
+
399
+ // https://eslint.org/docs/rules/prefer-regex-literals
400
+ "prefer-regex-literals": [
401
+ "error",
402
+ {
403
+ disallowRedundantWrapping: true,
404
+ },
405
+ ],
406
+
407
+ // require use of the second argument for parseInt()
408
+ // https://eslint.org/docs/rules/radix
409
+ radix: "error",
410
+
411
+ // require `await` in `async function` (note: this is a horrible rule that should never be used)
412
+ // https://eslint.org/docs/rules/require-await
413
+ "require-await": "off",
414
+
415
+ // Enforce the use of u flag on RegExp
416
+ // https://eslint.org/docs/rules/require-unicode-regexp
417
+ "require-unicode-regexp": "off",
418
+
419
+ // requires to declare all vars on top of their containing scope
420
+ // https://eslint.org/docs/rules/vars-on-top
421
+ "vars-on-top": "error",
422
+
423
+ // require immediate function invocation to be wrapped in parentheses
424
+ // https://eslint.org/docs/rules/wrap-iife.html
425
+ "wrap-iife": ["error", "outside", { functionPrototypeMethods: false }],
426
+
427
+ // require or disallow Yoda conditions
428
+ // https://eslint.org/docs/rules/yoda
429
+ yoda: "error",
430
+ },
431
+ }