eslint-stylistic-airbnb 2.0.0 → 3.0.0-rc.1

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/README.md CHANGED
@@ -1,99 +1,392 @@
1
1
  # eslint-stylistic-airbnb
2
2
 
3
- Airbnb config for ESLint with style rules via @stylistic plugin
3
+ ![NPM Downloads](https://img.shields.io/npm/dm/eslint-stylistic-airbnb)
4
+ ![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
4
5
 
5
- # Installation
6
+ A modern Airbnb ESLint config with the original formatting rules using [ESLint Stylistic](https://eslint.style/).
6
7
 
7
- Install all required dependencies
8
+ ## Table of Contents
8
9
 
9
- ```shell
10
+ - [Features](#features)
11
+ - [Why](#why)
12
+ - [Prerequisites](#prerequisites)
13
+ - [Installation](#installation)
14
+ - [Quickstart](#quickstart)
15
+ - [Configuration Reference](#configuration-reference)
16
+ - [Customizing Rules](#customizing-rules)
17
+ - [TypeScript Support](#typescript-support)
18
+ - [Migration Guide](#migration-guide)
19
+ - [Troubleshooting](#troubleshooting)
20
+ - [FAQ](#faq)
21
+ - [Contributing](#contributing)
22
+ - [License](#license)
23
+
24
+ ## Features
25
+
26
+ ✨ **Modern & Maintained** - Updated for ESLint 9+ with no deprecated rules or plugins
27
+
28
+ 🎨 **Formatting Included** - Uses [ESLint Stylistic](https://eslint.style/) instead of Prettier
29
+
30
+ 📦 **Multiple Formats** - Supports both flat config and legacy `.eslintrc`
31
+
32
+ 🔷 **TypeScript Ready** - Built-in TypeScript support
33
+
34
+ ⚛️ **Framework Support** - Dedicated configs for JSX-based frameworks, React and Vue.js
35
+
36
+ 🎯 **Flexible** - Choose from recommended, strict, or compatibility modes
37
+
38
+ 🔧 **Customizable** - Easy to override rules while maintaining the base style
39
+
40
+ ## Why
41
+
42
+ The original `eslint-config-airbnb` is not updated for a long time now, has compatibility issues and uses deprecated rules and plugins. This config addresses all of them:
43
+
44
+ - All deprecated rules are replaced with an updated alternatives
45
+ - All deprecated plugins removed or replaced with modern alternatives
46
+ - Any ESLint >= 8.57 is supported (including ESLint 9 of course)
47
+ - Both flat and legacy formats are supported
48
+ - TypeScript support
49
+ - Additional airbnb-inspired configs for other frameworks (JSX-based and Vue)
50
+
51
+ Big part of Airbnb codestyle are the formatting rules, so in order to follow airbnb codestyle as close as possible this config uses [ESLint Stylistic](https://eslint.style/) instead of `prettier`. Here is also a good article on this topic: [why not prettier](https://antfu.me/posts/why-not-prettier).
52
+
53
+ ## Prerequisites
54
+
55
+ - Node.js >= 16.x
56
+ - ESLint >= 8.57.0
57
+
58
+ ## Installation
59
+
60
+ Install the core packages:
61
+
62
+ ```bash
63
+ # npm
10
64
  npm install -D eslint @stylistic/eslint-plugin eslint-stylistic-airbnb
65
+
66
+ # pnpm
67
+ pnpm add -D eslint @stylistic/eslint-plugin eslint-stylistic-airbnb
68
+
69
+ # yarn
70
+ yarn add -D eslint @stylistic/eslint-plugin eslint-stylistic-airbnb
11
71
  ```
12
72
 
13
- Add following to your eslint config:
73
+ ## Quickstart
74
+
75
+ You can either use flat `eslint.config.js` (recommended) or legacy `.eslintrc` (in case you need it) configs.
14
76
 
77
+ > ⚠️ **Important Note on Plugins**: You must explicitly include the recommended presets for any plugins you use.
78
+ >
79
+ > The configs provided by this package (e.g., `flat/react`, `flat/vue`) only contain styling rules and Airbnb-specific overrides. They do not enable the core logic/linting rules of the underlying plugins.
80
+
81
+ ### Flat Config (ESLint 9+)
82
+
83
+ **JavaScript:**
15
84
  ```javascript
16
- // Flat config
17
- // eslint.config.mjs
18
- import stylistic from '@stylistic/eslint-plugin';
85
+ // eslint.config.js
19
86
  import airbnb from 'eslint-stylistic-airbnb';
20
87
 
21
88
  export default [
22
- airbnb,
23
- {
24
- files: ['**/*.{js,mjs,cjs,ts}'],
25
- plugins: {
26
- '@stylistic': stylistic,
27
- },
28
- },
89
+ airbnb.configs['flat/recommended'],
90
+ ];
91
+ ```
92
+
93
+ **TypeScript:**
94
+ ```javascript
95
+ // eslint.config.js
96
+ import airbnb from 'eslint-stylistic-airbnb';
97
+ import tseslint from 'typescript-eslint';
98
+
99
+ export default [
100
+ ...tseslint.configs.recommended,
101
+ airbnb.configs['flat/recommended'],
29
102
  ];
30
103
  ```
31
104
 
105
+ **React + JavaScript:**
106
+ ```javascript
107
+ // eslint.config.js
108
+ import airbnb from 'eslint-stylistic-airbnb';
109
+ import react from 'eslint-plugin-react';
110
+ import reactHooks from 'eslint-plugin-react-hooks';
111
+
112
+ export default [
113
+ airbnb.configs['flat/recommended'],
114
+ react.configs.flat.recommended,
115
+ reactHooks.configs.recommended,
116
+ airbnb.configs['flat/jsx'],
117
+ airbnb.configs['flat/react'],
118
+ ];
119
+ ```
120
+
121
+ **React + TypeScript:**
122
+ ```javascript
123
+ // eslint.config.js
124
+ import airbnb from 'eslint-stylistic-airbnb';
125
+ import react from 'eslint-plugin-react';
126
+ import reactHooks from 'eslint-plugin-react-hooks';
127
+ import tseslint from 'typescript-eslint';
128
+
129
+ export default [
130
+ ...tseslint.configs.recommended,
131
+ airbnb.configs['flat/recommended'],
132
+ react.configs.flat.recommended,
133
+ reactHooks.configs.recommended,
134
+ airbnb.configs['flat/jsx'],
135
+ airbnb.configs['flat/react'],
136
+ ];
137
+ ```
138
+
139
+ **Vue + JavaScript:**
140
+ ```javascript
141
+ // eslint.config.js
142
+ import airbnb from 'eslint-stylistic-airbnb';
143
+ import pluginVue from 'eslint-plugin-vue';
144
+
145
+ export default [
146
+ ...pluginVue.configs['flat/recommended'],
147
+ airbnb.configs['flat/recommended'],
148
+ airbnb.configs['flat/vue'],
149
+ ];
150
+ ```
151
+
152
+ **Vue + TypeScript:**
153
+ ```javascript
154
+ // eslint.config.js
155
+ import airbnb from 'eslint-stylistic-airbnb';
156
+ import pluginVue from 'eslint-plugin-vue';
157
+ import tseslint from 'typescript-eslint';
158
+
159
+ export default [
160
+ ...tseslint.configs.recommended,
161
+ ...pluginVue.configs['flat/recommended'],
162
+ airbnb.configs['flat/recommended'],
163
+ airbnb.configs['flat/vue'],
164
+ ];
165
+ ```
166
+
167
+ ### Legacy Config (.eslintrc)
168
+
169
+ **JavaScript:**
32
170
  ```javascript
33
- // Legacy config
34
171
  // .eslintrc.js
35
172
  module.exports = {
36
- plugins: ['@stylistic'],
37
- rules: {
38
- ...require('eslint-stylistic-airbnb').rules,
39
- },
40
- parserOptions: {
41
- ecmaVersion: 'latest',
42
- },
173
+ extends: ['eslint-stylistic-airbnb/recommended'],
43
174
  };
44
175
  ```
45
176
 
46
- # TypeScript
177
+ **React + JavaScript:**
178
+ ```javascript
179
+ // .eslintrc.js
180
+ module.exports = {
181
+ extends: [
182
+ 'eslint-stylistic-airbnb/recommended',
183
+ 'plugin:react/recommended',
184
+ 'plugin:react-hooks/recommended',
185
+ ],
186
+ };
187
+ ```
47
188
 
48
- If you use typescript, install additional dependency:
189
+ ## Configuration Reference
49
190
 
50
- ```shell
51
- npm install -D typescript-eslint
52
- ```
191
+ ### Base configs
192
+
193
+ Choose **one** of these as your foundation:
194
+
195
+ |Config|Config ID (Legacy)|Best For|Description|
196
+ |-|-|-|-|
197
+ |`flat/recommended`|`recommended`| New projects or gradual migration | All core Airbnb style rules: 2-space indentation, semicolons, trailing commas, single quotes, const/let over var, prefer-destructuring. Includes modern rules (`prefer-object-has-own`, `no-constant-binary-expression`) and TypeScript member delimiters. |
198
+ |`flat/strict`|`strict` | Maximum consistency enforcement | Everything in `recommended` **plus** stricter rules: disallows single-line ternaries, enforces function expressions over declarations, requires comments above code (not inline). ⚠️ May require refactoring. |
199
+ |`flat/compat`|`compat` | Upgrading from v1.x | Backward-compatible with previous package versions. Use when migrating to preserve existing behavior before adopting new rules. |
53
200
 
54
- And add following to your eslint config:
201
+ ### Addon configs
55
202
 
203
+ Add **any combination** of these to extend base configs:
204
+
205
+ |Config|Dependencies|Description|
206
+ |-|-|-|
207
+ |`flat/addon-jsx`| None | JSX/TSX formatting for React/Preact/Solid: PascalCase components, double quotes, 2-space indentation, self-closing tags, multiline wrapped in parens, one prop per line (multiline). |
208
+ |`flat/addoniterators`| None | Relaxes iterator restrictions: allows `for...of` loops. Still disallows `for...in`, `with` statements, and labeled statements. |
209
+ |`flat/addon-react` | `eslint-plugin-react` | React component rules: prop types validation, no deprecated APIs, component method ordering, lifecycle conventions, no array index keys, destructured props, function component style. |
210
+ |`flat/addon-vue` | `eslint-plugin-vue` | Vue 3 SFC conventions: block order (script/template/style), PascalCase naming, no useless mustaches/v-bind, boolean prop shorthand, separate static classes. |
211
+ |`flat/addon-vue-ts` | `eslint-plugin-vue`<br/>`typescript-eslint` | TypeScript in Vue: enforces `<script lang="ts">` and type-based prop definitions. Sets up TS parser for Vue files. |
212
+ | `flat/addon-import` | `eslint-plugin-import-x` | 🛠️ WIP 🛠️ Adds import-related rules |
213
+
214
+ ## Customizing Rules
215
+
216
+ You can override any rule to fit your project's needs:
217
+
218
+ **Flat Config:**
56
219
  ```javascript
57
- // Flat config
58
- // eslint.config.mjs
59
- import tseslint from 'typescript-eslint';
60
- import stylistic from '@stylistic/eslint-plugin';
220
+ // eslint.config.js
61
221
  import airbnb from 'eslint-stylistic-airbnb';
62
222
 
63
223
  export default [
64
- airbnb,
65
- ...tseslint.configs.recommended,
224
+ airbnb.configs['flat/recommended'],
66
225
  {
67
- files: ['**/*.{js,mjs,cjs,ts}'],
68
- plugins: {
69
- '@stylistic': stylistic,
226
+ rules: {
227
+ // Relax specific rules
228
+ '@stylistic/indent': ['error', 4], // Use 4 spaces instead of 2
229
+ 'no-console': 'warn', // Warn instead of error
230
+ 'max-len': ['error', { code: 120 }], // Increase line length
70
231
  },
71
232
  },
72
233
  ];
73
234
  ```
74
235
 
236
+ **Legacy Config:**
75
237
  ```javascript
76
- // Legacy config
77
238
  // .eslintrc.js
78
239
  module.exports = {
79
- plugins: [
80
- '@typescript-eslint',
81
- '@stylistic',
82
- ],
83
- parser: '@typescript-eslint/parser',
240
+ extends: ['eslint-stylistic-airbnb/recommended'],
84
241
  rules: {
85
- ...require('eslint-stylistic-airbnb').rules,
242
+ '@stylistic/indent': ['error', 4],
243
+ 'no-console': 'warn',
244
+ 'max-len': ['error', { code: 120 }],
86
245
  },
87
246
  };
88
247
  ```
89
248
 
90
- # Notes
249
+ ## TypeScript Support
250
+
251
+ This config works with TypeScript out of the box. For TypeScript projects, you'll need to configure the parser, the preferred way is to use `typescript-eslint` config:
252
+
253
+ **Flat Config:**
254
+ ```javascript
255
+ // eslint.config.js
256
+ import airbnb from 'eslint-stylistic-airbnb';
257
+ import tseslint from 'typescript-eslint';
258
+
259
+ export default [
260
+ ...tseslint.configs.recommended,
261
+ airbnb.configs['flat/recommended'],
262
+ ];
263
+ ```
264
+
265
+ ## Migration Guide
266
+
267
+ ### From `eslint-config-airbnb`
268
+
269
+ 1. **Uninstall the old package:**
270
+ ```bash
271
+ npm uninstall eslint-config-airbnb eslint-config-airbnb-base
272
+ ```
273
+
274
+ 2. **Install this package** (see [Installation](#installation))
275
+
276
+ 3. **Update your config:**
277
+ - Flat config: Replace `airbnb` with `airbnb.configs['flat/recommended']`
278
+ - Legacy: Replace `'airbnb'` with `'eslint-stylistic-airbnb/recommended'`
279
+
280
+ 4. **Remove Prettier** (if using):
281
+ ```bash
282
+ npm uninstall prettier eslint-config-prettier eslint-plugin-prettier
283
+ ```
284
+
285
+ 5. **Test and adjust** rules as needed
286
+
287
+ ### From v2.x of this package
288
+
289
+ Use the `flat/compat` or `compat` config to maintain v2.x behavior:
290
+
291
+ ```javascript
292
+ // eslint.config.js (flat config)
293
+ import airbnb from 'eslint-stylistic-airbnb';
294
+
295
+ export default [
296
+ airbnb.configs['flat/compat'],
297
+ ];
298
+ ```
299
+
300
+ ```javascript
301
+ // .eslintrc.js (legacy config)
302
+ module.exports = {
303
+ extends: ['eslint-stylistic-airbnb/compat'],
304
+ };
305
+ ```
306
+
307
+ ## Troubleshooting
308
+
309
+ ### Conflicts with Prettier
310
+
311
+ This config is designed to **replace** Prettier. If you have Prettier installed:
312
+
313
+ 1. Remove Prettier and related ESLint plugins
314
+ 2. Remove `.prettierrc` and `prettier.config.js`
315
+ 3. Update your IDE to use ESLint for formatting instead of Prettier
316
+
317
+ ### Plugin Not Found Errors
318
+
319
+ Ensure you've installed the required peer dependencies for the configs you're using:
320
+
321
+ - `flat/react` requires: `eslint-plugin-react`
322
+ - `flat/vue` requires: `eslint-plugin-vue`
323
+ - `flat/vue-ts` requires: `eslint-plugin-vue` and `typescript-eslint`
324
+
325
+ ### TypeScript Parsing Errors
326
+
327
+ Make sure that you use any of `typescript-eslint` configs:
328
+
329
+ ```javascript
330
+ import tseslint from 'typescript-eslint';
331
+
332
+ export default [
333
+ ...tseslint.configs.recommended,
334
+ ];
335
+ ```
336
+
337
+ ## FAQ
338
+
339
+ ### Should I use this instead of Prettier?
340
+
341
+ Yes! This config provides formatting through ESLint rules using [ESLint Stylistic](https://eslint.style/), which more closely matches the original styleguide and provides better integration with your linting workflow. See [Why I don't use Prettier](https://antfu.me/posts/why-not-prettier) for more context.
342
+
343
+ ### Can I use this with TypeScript?
344
+
345
+ Absolutely! This config works with TypeScript out of the box. See the [TypeScript Support](#typescript-support) section for setup instructions.
346
+
347
+ ### Which base config should I choose?
348
+
349
+ - **`flat/recommended`** - Best for most projects. Includes all essential Airbnb rules with modern additions.
350
+ - **`flat/strict`** - If you want to follow styleguide more closely and if you are willing to refactor code to meet stricter formatting rules.
351
+ - **`flat/compat`** - Only if migrating from v2.x of this package.
352
+
353
+ ### Do I need to install React/Vue plugins?
354
+
355
+ Only if you're using the React or Vue addons. The base config works standalone for JavaScript/TypeScript projects.
356
+
357
+ ### Why do I get "plugin not found" errors?
358
+
359
+ Make sure you've installed the peer dependencies for any addon configs you're using. See [Configuration Reference](#configuration-reference) for the complete list of optional dependencies.
360
+
361
+ ### Can I override specific rules?
362
+
363
+ Yes! See the [Customizing Rules](#customizing-rules) section for examples.
364
+
365
+ ### Is this compatible with ESLint 9?
366
+
367
+ Yes, ESLint 9 is fully supported using the flat config format.
368
+
369
+ ### How do I migrate from `eslint-config-airbnb`?
370
+
371
+ See the [Migration Guide](#migration-guide) for step-by-step instructions.
372
+
373
+ ## Contributing
374
+
375
+ Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
376
+
377
+ ## License
378
+
379
+ [MIT](https://opensource.org/licenses/MIT)
380
+
381
+ ## Credits
382
+
383
+ - Based on the original [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)
384
+ - Uses [@stylistic/eslint-plugin](https://eslint.style/) for formatting rules
385
+ - Inspired by the philosophy of [Why I don't use Prettier](https://antfu.me/posts/why-not-prettier) by Anthony Fu
91
386
 
92
- This config is created from the base airbnb config as is, with no changes to original rules
387
+ ## Related Links
93
388
 
94
- - rules that required newer eslint version are enabled
95
- - node related rules are not implemented
96
- - import rules are not implemented
97
- - react rules are not implemented (except of some jsx style options)
98
- - `func-style` rule is turned off, just like in original config (airbnb config contradicts with airbnb styleguide, this
99
- option set to be "backward-compatible")
389
+ - [ESLint Documentation](https://eslint.org/)
390
+ - [ESLint Stylistic](https://eslint.style/)
391
+ - [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)
392
+ - [Original eslint-config-airbnb](https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb)
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ const rules = require('./flat/addon-iterators');
4
+
5
+ module.exports = {
6
+ rules,
7
+ };
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const rules = require('./flat/addon-jsx');
4
+
5
+ module.exports = {
6
+ plugins: ['@stylistic'],
7
+ rules,
8
+ parserOptions: {
9
+ ecmaFeatures: {
10
+ jsx: true,
11
+ },
12
+ },
13
+ };
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ const rules = require('./flat/addon-react');
4
+
5
+ module.exports = {
6
+ rules,
7
+ };
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ const { rules } = require('./flat/compat');
4
+
5
+ module.exports = {
6
+ plugins: ['@stylistic'],
7
+ rules,
8
+ };
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ const rules = require('../../rules/import').rules;
4
+
5
+ module.exports = {
6
+ rules,
7
+ };
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+
3
+ module.exports = {
4
+ name: 'airbnb:addon-iterators',
5
+ rules: {
6
+ 'no-restricted-syntax': [
7
+ 'error',
8
+ {
9
+ selector: 'ForInStatement',
10
+ message: 'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.',
11
+ },
12
+ {
13
+ selector: 'LabeledStatement',
14
+ message: 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.',
15
+ },
16
+ {
17
+ selector: 'WithStatement',
18
+ message: '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.',
19
+ },
20
+ ],
21
+ },
22
+ };
@@ -0,0 +1,54 @@
1
+ 'use strict';
2
+
3
+ // https://github.com/airbnb/javascript/blob/master/packages/eslint-config-airbnb/rules/react.js
4
+
5
+ module.exports = {
6
+ name: 'airbnb:addon-jsx',
7
+ plugins: {
8
+ get ['@stylistic']() {
9
+ return require('@stylistic/eslint-plugin');
10
+ },
11
+ },
12
+ rules: {
13
+ '@stylistic/jsx-pascal-case': ['error', { allowAllCaps: true }],
14
+ "@stylistic/jsx-closing-tag-location": "error",
15
+ "@stylistic/jsx-closing-bracket-location": ["error", "line-aligned"],
16
+ '@stylistic/jsx-quotes': ['error', 'prefer-double'],
17
+ '@stylistic/jsx-curly-spacing': ["error", { when: 'never', allowMultiline: true }],
18
+ '@stylistic/jsx-wrap-multilines': ['error', {
19
+ declaration: 'parens-new-line',
20
+ assignment: 'parens-new-line',
21
+ return: 'parens-new-line',
22
+ arrow: 'parens-new-line',
23
+ condition: 'parens-new-line',
24
+ logical: 'parens-new-line',
25
+ prop: 'parens-new-line',
26
+ }],
27
+ '@stylistic/jsx-self-closing-comp': 'error',
28
+ // deprecated, but still needed for a proper formatting
29
+ '@stylistic/jsx-indent': ['error', 2],
30
+ '@stylistic/jsx-indent-props': ['error', 2],
31
+ '@stylistic/jsx-max-props-per-line': ['error', { maximum: 1, when: 'multiline' }],
32
+ '@stylistic/jsx-first-prop-new-line': ['error', 'multiline-multiprop'],
33
+ '@stylistic/jsx-equals-spacing': ['error', 'never'],
34
+ '@stylistic/jsx-tag-spacing': ['error', {
35
+ closingSlash: 'never',
36
+ beforeSelfClosing: 'always',
37
+ afterOpening: 'never',
38
+ beforeClosing: 'never',
39
+ }],
40
+ '@stylistic/jsx-curly-brace-presence': ['error', { props: 'never', children: 'never' }],
41
+ '@stylistic/jsx-one-expression-per-line': ['error', { allow: 'single-child' }],
42
+ '@stylistic/jsx-curly-newline': ['error', {
43
+ multiline: 'consistent',
44
+ singleline: 'consistent',
45
+ }],
46
+ },
47
+ languageOptions: {
48
+ parserOptions: {
49
+ ecmaFeatures: {
50
+ jsx: true,
51
+ },
52
+ },
53
+ },
54
+ };