Opinionated and flexible ESLint config with TypeScript, Vue, Nuxt, Next.js, Astro support and oxlint / oxfmt integration.
- Modern: ESLint flat config with pregenerated TypeScript definitions
- Strict: Opinionated and rigorous linting rules for better code quality
- Flexible: Framework-agnostic with optional plugins
- Zero-config: Works out of the box, customize as needed
- Fast: Optional oxlint / oxfmt integration (50-100x faster linting and formatting)
- Actively maintained and production-tested across diverse client projects at FANS — both new and existing
Default plugins: @eslint/js, import-x,
promise, n, de-morgan,
unicorn
Optional plugins: @typescript-eslint, vue,
astro, vitest, prettier,
@stylistic, perfectionist,
vuejs-accessibility, eslint-plugin-query
Inspect rules · View oxlint unsupported rules
- Table of Contents
- Usage
- Customization
- Framework Support
- Oxlint and Oxfmt Support
- Inspect
- Inspired By
- Contributing
Install the package:
pnpm add -D eslint-config-fans eslintCreate eslint.config.js in your project root:
import { defineConfig } from 'eslint-config-fans'
export default defineConfig({
// Enable features based on your project
typescript: true,
vue: true,
})interface DefineConfigOptions {
// Custom ignore patterns
ignores?: string[]
// Control strictness level
strict?: boolean // default: true
// Enable TypeScript support
typescript?: boolean // default: false
// Enable Vue.js support
vue?: boolean | VueOptions // default: false
// Enable Astro support
astro?: boolean // default: false
// Enable test files support (Vitest)
test?: boolean // default: false
// Configure code formatting integration
formatter?: FormatterOptions | "prettier" | "stylistic" | false // default: false
// Enable unicorn rules (opinionated best practices)
unicorn?: boolean // default: true
// Enable import/export sorting
perfectionist?: boolean // default: false
// Enable oxlint support for better performance
oxlint?: boolean | OxlintOptions // default: false
// Enable TanStack Query support
query?: boolean // default: false
}By default, the config ignores common directories and files, and automatically
respects your .gitignore patterns. You can extend the ignore patterns:
export default defineConfig({
ignores: [
'custom-dist/**',
'legacy-code/**',
]
})By default, the config operates in strict mode, which enables more opinionated linting rules for better code quality. When disabled, the configuration becomes less strict and more permissive:
export default defineConfig({
strict: false,
})For new projects, we recommend keeping strict mode enabled.
For legacy codebases or gradual adoption, you may want
to start with strict: false and enable it later.
You can choose between Prettier and ESLint Stylistic for code formatting:
- Prettier (
formatter: 'prettier'): Uses Prettier for formatting, disables conflicting rules - Stylistic (
formatter: 'stylistic'): Uses ESLint Stylistic rules for formatting - Disable (
formatter: false): Disables formatting if you prefer to use external formatter like oxfmt, biome, etc.
When using formatter: 'stylistic', you can customize formatting rules.
See StylisticOptions for all available options:
export default defineConfig({
formatter: {
type: 'stylistic',
options: {
indent: 2,
quotes: 'single',
semi: false,
},
},
})Prettier can be configured through standard .prettierrc files
or prettier.config.js. The ESLint config will automatically detect
and respect your Prettier settings.
You can extend the configuration with additional ESLint configs and use exported globs for precise file targeting:
import { defineConfig, GLOB_TS } from 'eslint-config-fans'
export default defineConfig(
{
typescript: true,
},
{
files: [GLOB_TS],
rules: {
'@typescript-eslint/no-misused-promises': 'off',
},
}
)Full support for Vue projects with vue-accessibility and TypeScript integration:
export default defineConfig({
typescript: true,
vue: {
// Enable vuejs-accessibility rules
a11y: true,
// Ignore undefined components for the `vue/no-undef-components` rule
extendUndefComponents: ['CustomComponent'],
}
})This enables linting for .vue files with proper TypeScript support
and Vue-specific rules.
Full compatibility with Nuxt ESLint:
import { defineConfig } from 'eslint-config-fans'
import withNuxt from './.nuxt/eslint.config.mjs'
export default withNuxt(
defineConfig(
{
typescript: true,
vue: {
a11y: true,
},
},
),
)Full compatibility with Next.js ESLint:
import { defineConfig } from 'eslint-config-fans'
import configNextCoreWebVitals from 'eslint-config-next/core-web-vitals'
import configNextTypescript from 'eslint-config-next/typescript'
export default defineConfig(
{
typescript: true,
},
...configNextCoreWebVitals,
...configNextTypescript,
)Full support for Astro projects with TypeScript integration:
export default defineConfig({
typescript: true,
astro: true,
})This enables linting for .astro files with proper TypeScript support
and Astro-specific rules.
This config includes built-in support for oxlint — a blazing-fast JavaScript linter written in Rust by void(0). Oxlint is 50-100 times faster than ESLint and designed for performance-critical workflows, making it perfect for large codebases and CI environments.
Note: Oxlint doesn't support all ESLint rules yet. Check the generated list of unsupported rules to see which rules from this config are not available in oxlint.
We recommend following the official migration guide for the most up-to-date instructions.
-
Create your ESLint config as described above
-
Install oxlint:
pnpm add -D oxlint
-
Generate oxlint configuration from your ESLint config:
pnpx @oxlint/migrate ./eslint.config.js --type-aware --js-plugins
This command migrates your ESLint configuration to oxlint format:
--type-aware: Generates configuration for TypeScript type-aware rules--js-plugins: Migrates JavaScript plugin rules to their oxlint equivalents
Note: After migration, you may need to manually install some JavaScript plugins to your dev dependencies that oxlint requires but doesn’t install automatically.
-
Enable oxlint in your configuration:
export default defineConfig({ typescript: true, oxlint: true, // Enable oxlint support })
For TypeScript projects, you might want to enable DTS checking:
export default defineConfig({ typescript: true, oxlint: { dts: true, // Check .d.ts files with TypeScript rules }, })
Important: We still recommend running oxlint and ESLint together, as oxlint doesn’t support all ESLint rules yet. Use oxlint for fast feedback during development and ESLint for comprehensive checks in CI.
If you want to use oxfmt for formatting instead of Prettier or Stylistic:
-
Disable formatting in your ESLint config (see Formatting for details):
export default defineConfig({ typescript: true, formatter: false, // Disable ESLint formatting rules })
-
Install oxfmt:
pnpm add -D oxfmt
-
Initialize oxfmt configuration:
pnpx oxfmt --init
This creates an
oxc.jsonfile with formatter configuration. -
Add format scripts to your
package.json:{ "scripts": { "format": "oxfmt", "format:check": "oxfmt --check" } }
For more details, see the oxfmt quickstart guide.
You can inspect your ESLint configuration using the interactive configuration inspector:
pnpx @eslint/config-inspector --config eslint.config.jsOr add it as a script to your package.json:
{
"scripts": {
"lint:inspect": "pnpx @eslint/config-inspector --config eslint.config.js"
}
}This configuration is inspired by and builds upon the excellent work of:
This package can be installed directly from the repository, thanks to our
pure JavaScript implementation with TypeScript definitions provided
via .d.ts files — no compilation step required.
pnpm add -D github:fandsdev/eslint-config-fansAll versions follow Semantic Versioning.