eslint-config-connorjs
v1.1.1
Published
@connorjs’s preferred ESLint configuration. With ESLint flat config.
Downloads
20
Readme
eslint-config-connorjs
My (@connorjs) preferred ESLint configuration. With ESLint flat config.
Use it directly (§ Install) or take inspiration from it (§ Rules and reasoning).
🛑 IMPORTANT
eslint-comments/require-description is the single most important rule to configure! Please use it.
🟢 Tip: I highly recommend eslint-plugin-unicorn, which my config uses.
Table of contents
Install
Add the dependency
npm i -D eslint-config-connorjs
Include the config in your ESLint flat config.
import connorjsConfig from "eslint-config-connorjs"; export default [ // earlier configuration ...connorjsConfig, // later ];
To learn more about ESLint flat config, check out the blog posts or the documentation.
Project structure
The lib directory contains the ESLint configuration files.
It groups them by “use case.”
A use case could represent an entire language (html
or json
for example) or a tool (react
or vitest
).
Splitting by use case helps to copy desired configuration or building a functional form of the ESLint config. (See Sheriff for an example of the functional form.)
Rules and reasoning
The remainder of the README discusses the rules, configurations, and plugins used and why I used them.
The 🔧 emoji indicates that configured rules are automatically fixable with --fix
.
🟢 Tip: The source code has inline comments that may provide more detail.
Base rules
The base rules config apply to all file types.
Configures ESLint linter options.
- reportUnusedDisableDirectives to keep code clean and up to date.
Includes eslint-plugin-eslint-comments and enforces comment descriptions (eslint-comments/require-description) to document why the code should ignore a configured ESLint rule.
Includes eslint-config-prettier to turns off all rules that are unnecessary or might conflict with Prettier.
🔧 Enforces template literals (backtick strings) to allow easier change to interpolation with eslint/quotes.
Configures the global ignores.
JSON
The JSON config applies to all JSON files. It handles JSONC (JSON with comments) and JSONC-like files.
Configures jsonc-eslint-parser as the parser for the
.json
and.jsonc
files.It does not lint
package-lock.json
.Includes eslint-plugin-jsonc and registers its
recommended-with-json
andprettier
rule sets.🔧 Configures sorting rules to standardize the order (no need to think or worry about the “best” order) and reduces merge conflicts. Feel free to
eslint-disable
at call sites.Allows comments in JSONC and JSONC-like files (for example,
tsconfig.json
).🔧 Configures an explicit sort order for
package.json
keys. See the code for details.🔷 Note: This overrides the previous jsonc/sort-keys configuration. You can configure specific sort orders for other files using similar logic.
JavaScript and TypeScript
The JS and TS config applies to all JS and
TS files: cjs,js,ts,tsx
. The largest configuration set!
Configures language options.
ecmaVersion: latest
because projects use bundlers or other build tools to transpile to target versions.Includes isomorphic globals (shared by node and the browser) via globals
Also see the @typescript-eslint/parser documentation
🔧 Configures sorting rules to standardize the order (no need to think or worry about the “best” order) and reduces merge conflicts. Feel free to
eslint-disable
at call sites. They are case-insensitive.🔧 @typescript-eslint/member-ordering with required properties first
Includes @eslint/js
recommended
rule set.Includes eslint-plugin-sonarjs
recommended
rule set.Includes eslint-plugin-unicorn
recommended
rule set and configures additional rules from unicorn. Some specific call-outs follow.🔧 Configures an allow list for unicorn/prevent-abbreviations to allow some abbreviations. Example: Allow
props
, which React commonly uses.🔧 Configures patterns for unicorn/string-content to enforce better string content. Example: Use unicode arrow
→
instead of hyphen and greater than (->
).The auto-fix feature makes this rule very useful. See the source code for a “smart quotes” pattern.
Uses typescript-eslint and includes its
recommended-type-checked
andstylistic-type-checked
rule sets.🔧 Configures @typescript-eslint/consistent-type-definitions to enforce using
type
instead ofinterface
(as the default).Interfaces use declaration merging, which I do not recommend as the default. See the Differences Between Type Aliases and Interfaces documentation.
🔧 Configures @typescript-eslint/no-non-null-assertion to require a comment via
eslint-disable
when needed. It allows non-null assertions in test files.
Uses eslint-plugin-simple-import-sort and eslint-plugin-import to configure import rules. Some specific call-outs follow.
🔧 Includes
simple-import-sort/imports
andsimple-import-sort/exports
to sort the imports and re-exports. See the Sort order docs.I recommend the default configuration instead of creating your own order.
Includes eslint-plugin-import
recommended
rule set.Configures import/no-default-export to disallow default exports.
I have experienced various issues resulting from default exports over the years, so I strongly recommend configuring this rule. You can always
eslint-disable
at the call site when you need it and explain why (example: dynamic imports for React code-splitting point).- Naming exports leads to a stronger contract and can help refactoring.
- You can use
as
syntax to rename named exports very easily, so the supposed benefit of “name default exports whatever you want” has little benefit in practice. - I want to add more of my reasons, so TODO!
The ESLint configuration opts-out known configuration files that require default exports (example: storybook files).
Configures import/no-anonymous-default-export to disallow anonymous default exports in the case that you
eslint-disable
theimport/no-default-export
rule.🔧 Uses @typescript-eslint/consistent-type-imports and import/consistent-type-specifier-style to enforce consistent usage of type imports.
We need both rules for best fix-it developer experience: one to add
type
and the other to fix the placement.
React
The react config applies to all typescript files (ts
and tsx
) and only makes sense to use in a React project.
Uses eslint-plugin-jsx-a11y and its
recommended
rule set.Uses eslint-plugin-react and its
recommended
andjsx-runtime
rule sets.Uses eslint-plugin-react-hooks and its
recommended
rule set.Configures react/destructuring-assignment to disallow destructuring props. (Controversial, I know.)
I find it harder to update components that use destructuring. Plus I think it looks bad with inline types given TypeScript usage.
Configures react/forbid-component-props to disallow props. (Example:
style
to disallow inline styles.)🔧 Configures [react/function-component-definition] to enforce component definition consistency.
Uses “function declarations” for named components because they are the only way to support generics in TSX, so using it for consistency. Remember: This will auto-fix.
Uses “arrow functions” for unnamed components to emphasize unnamed and for nice lambda readability (example: pass to
map
).🔧 Enables react/hook-use-state to enforce symmetric naming of the
useState
hook value and setter variables.🔧 Configures react/jsx-boolean-value and react/jsx-curly-brace-presence to enforce consistent JSX styles. See the code for details.
Configures the following rules to force a comment explaining the use case. While this may seem like extra work, it helps catch improper usage.
- react/jsx-no-leaked-render
- react/jsx-props-no-spreading
- react/no-array-index-key
- react/no-danger
HTML
The HTML config applies to all HTML files.
Uses html-eslint.
Includes the
recommended
ruleset and accessibility and best practice oriented rules. See the code for details, but some specific call-outs follow.@html-eslint/id-naming-convention to enforce kebab case for
id
naming.@html-eslint/no-inline-styles to disallow inline styles, mostly for Content Security Policy (CSP) reasons.
Even if you allow
unsafe-inline
for the CSP, this rule would also require explanations for using inline styles instead of CSS witheslint-disable
.@html-eslint/no-skip-heading-levels to disallow skipping heading levels.
@html-eslint/no-target-blank to disallow usage of unsafe
target='_blank'
.