@rhapsodic/eslint-config
v1.0.2
Published
Rhapsodic's ESLint config
Keywords
Readme
@rhapsodic/eslint-config
- Auto fix for formatting
- Reasonable defaults, best practices, only one line of config
- Designed to work with TypeScript, Vue. Out-of-box.
- Opinionated, but very customizable
- ESLint Flat config, compose easily!
- Style principle: Minimal for reading, stable for diff, consistent
- Sorted imports, dangling commas
- Single quotes, no semi
- Using ESLint Stylistic
- Requires ESLint v9.5.0+
Install
pnpm i -D eslint @rhapsodic/eslint-configAnd create eslint.config.mjs or eslint.config.ts in your project root:
// eslint.config.mjs
import { rhapsodic } from '@rhapsodic/eslint-config'
export default rhapsodic()If you still use some configs from the legacy eslintrc format, you can use the @eslint/eslintrc package to convert them to the flat config.
// eslint.config.mjs
import { rhapsodic } from '@rhapsodic/eslint-config'
import { FlatCompat } from '@eslint/eslintrc'
const compat = new FlatCompat()
export default rhapsodic(
{
ignores: [],
},
// Legacy config
...compat.config({
extends: [
'eslint:recommended',
// Other extends...
],
})
// Other flat configs...
)Note that
.eslintignoreno longer works in Flat config, see customization for more details.
Add script for package.json
For example:
{
"scripts": {
"lint": "eslint",
"lint:fix": "eslint --fix"
}
}IDE Support (auto fix on save)
Install VS Code ESLint extension
Add the following settings to your .vscode/settings.json:
{
// Disable the default formatter, use eslint instead
"prettier.enable": false,
"editor.formatOnSave": false,
// Auto fix
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},
// Enable eslint for all supported languages
"eslint.validate": [
"javascript",
"typescript",
"vue"
]
}Customization
Normally you only need to import the rhapsodic preset:
// eslint.config.js
import { rhapsodic } from '@rhapsodic/eslint-config'
export default rhapsodic()And that's it! Or you can configure each integration individually, for example:
// eslint.config.js
import { rhapsodic } from '@rhapsodic/eslint-config'
export default rhapsodic({
// `.eslintignore` is no longer supported in Flat config, use `ignores` instead
// The `ignores` option in the option (first argument) is specifically treated to always be global ignores
// And will **extend** the config's default ignores, not override them
// You can also pass a function to modify the default ignores
ignores: [
'**/fixtures',
// ...globs
],
// Enable stylistic formatting rules
stylistic: true,
// Or customize the stylistic rules
stylistic: {
indent: 2, // 4, or 'tab'
quotes: 'single', // or 'double'
},
// TypeScript and Vue are autodetected, you can also explicitly enable them:
typescript: true,
vue: true,
})The rhapsodic factory function also accepts any number of arbitrary custom config overrides:
// eslint.config.js
import { rhapsodic } from '@rhapsodic/eslint-config'
export default rhapsodic(
{
// Configures for rhapsodic's config
},
// From the second arguments they are ESLint Flat Configs
// you can have multiple configs
{
files: ['**/*.ts'],
rules: {},
},
{
rules: {},
},
)Going more advanced, you can also import fine-grained configs and compose them as you wish:
We wouldn't recommend using this style in general unless you know exactly what they are doing, as there are shared options between configs and might need extra care to make them consistent.
// eslint.config.js
import {
combine,
ignores,
imports,
javascript,
stylistic,
typescript,
unicorn,
vue,
} from '@rhapsodic/eslint-config'
export default combine(
ignores(),
javascript(/* Options */),
imports(),
unicorn(),
typescript(/* Options */),
stylistic(),
vue(),
)Check out the configs and factory for more details.
Thanks to sxzz/eslint-config for the inspiration and reference.
Rules Overrides
Certain rules would only be enabled in specific files, for example, ts/* rules would only be enabled in .ts files and vue/* rules would only be enabled in .vue files. If you want to override the rules, you need to specify the file extension:
// eslint.config.js
import { rhapsodic } from '@rhapsodic/eslint-config'
export default rhapsodic(
{
vue: true,
typescript: true
},
{
// Remember to specify the file glob here, otherwise it might cause the vue plugin to handle non-vue files
files: ['**/*.vue'],
rules: {
'vue/operator-linebreak': ['error', 'before'],
},
},
{
// Without `files`, they are general rules for all files
rules: {
'style/semi': ['error', 'never'],
},
}
)We also provided the overrides options in each integration to make it easier:
// eslint.config.js
import { rhapsodic } from '@rhapsodic/eslint-config'
export default rhapsodic({
vue: {
overrides: {
'vue/operator-linebreak': ['error', 'before'],
},
},
typescript: {
overrides: {
'ts/consistent-type-definitions': ['error', 'interface'],
},
},
yaml: {
overrides: {
// ...
},
},
})Config Composer
Since v2.10.0, the factory function rhapsodic() returns a FlatConfigComposer object from eslint-flat-config-utils where you can chain the methods to compose the config even more flexibly.
// eslint.config.js
import { rhapsodic } from '@rhapsodic/eslint-config'
export default rhapsodic()
.prepend(
// some configs before the main config
)
// overrides any named configs
.override(
'rhapsodic/stylistic/rules',
{
rules: {
'style/generator-star-spacing': ['error', { after: true, before: false }],
}
}
)
// rename plugin prefixes
.renamePlugins({
'old-prefix': 'new-prefix',
// ...
})
// ...Vue
Vue support is detected automatically by checking if vue is installed in your project. You can also explicitly enable/disable it:
// eslint.config.js
import { rhapsodic } from '@rhapsodic/eslint-config'
export default rhapsodic({
vue: true
})Vue Accessibility
To enable Vue accessibility support, you need to explicitly turn it on:
// eslint.config.js
import { rhapsodic } from '@rhapsodic/eslint-config'
export default rhapsodic({
vue: {
a11y: true
},
})Running npx eslint should prompt you to install the required dependencies, otherwise, you can install them manually:
pnpm i -D eslint-plugin-vuejs-accessibilityLint Staged
If you want to apply lint and auto-fix before every commit, you can add the following to your package.json:
{
"simple-git-hooks": {
"pre-commit": "pnpm lint-staged"
},
"lint-staged": {
"*": "eslint --fix"
}
}and then
pnpm i -D lint-staged simple-git-hooks
// to active the hooks
npx simple-git-hooksView what rules are enabled
I built a visual tool to help you view what rules are enabled in your project and apply them to what files, @eslint/config-inspector
Go to your project root that contains eslint.config.js and run:
npx @eslint/config-inspectorVersioning Policy
This project follows Semantic Versioning for releases. However, since this is just a config and involves opinions and many moving parts, we don't treat rules changes as breaking changes.
Changes Considered as Breaking Changes
- Node.js version requirement changes
- Huge refactors that might break the config
- Plugins made major changes that might break the config
- Changes that might affect most of the codebases
Changes Considered as Non-breaking Changes
- Enable/disable rules and plugins (that might become stricter)
- Rules options changes
- Version bumps of dependencies
License
MIT License © 2019-PRESENT Anthony Fu MIT License © 2025-PRESENT Svyatoslav Fyodorov
