---
title: "Overview"
description: "How the vinicuncaESLint factory combines its options, your own flat configs and the composer API into one ESLint config."
canonical_url: "https://vinicunca.dev/eslint/configuration"
---
# Overview

> How the vinicuncaESLint factory combines its options, your own flat configs and the composer API into one ESLint config.

## The factory

Everything starts from the `vinicuncaESLint` factory, a named export of the package:

```ts
function vinicuncaESLint(
  options?: OptionsConfig & Omit<TypedFlatConfigItem, 'files' | 'ignores'>,
  ...userConfigs: Array<Awaitable<
    TypedFlatConfigItem | Array<TypedFlatConfigItem> | FlatConfigComposer | Array<Linter.Config>
  >>
): FlatConfigComposer<TypedFlatConfigItem, ConfigNames>;
```

- The **first argument** holds global options that turn integrations on or off and tune them.
- **Every following argument** is a regular ESLint flat config (or an array, a promise, or another composer) appended after the generated configs.
- The **return value** is a [`FlatConfigComposer`](https://github.com/antfu/eslint-flat-config-utils#composer). ESLint accepts it directly as the default export, and you can chain methods on it to edit the generated configs.

```js [eslint.config.js]
import { vinicuncaESLint } from '@vinicunca/eslint-config';

export default vinicuncaESLint(
  // 1. Options
  {
    type: 'lib',
    typescript: {
      tsconfigPath: 'tsconfig.json',
    },
  },

  // 2. Extra flat configs, applied in order
  {
    files: ['**/*.ts'],
    rules: {
      'ts/no-explicit-any': 'error',
    },
  },
  {
    rules: {
      'no-console': 'off',
    },
  },
)
  // 3. Composer methods
  .override('vinicunca/stylistic/rules', {
    rules: {
      'style/max-statements-per-line': 'off',
    },
  });
```

## Options

Each integration is controlled by an option with the same name. Most accept `true`/`false`, or an object to configure it:

```js [eslint.config.js]
import { vinicuncaESLint } from '@vinicunca/eslint-config';

export default vinicuncaESLint({
  // Turn an integration off
  yaml: false,

  // Turn one on with defaults
  react: true,

  // Configure it with an object (also turns it on)
  vue: {
    a11y: true,
    overrides: {
      'vue/no-v-html': 'error',
    },
  },
});
```

Most integrations accept an `overrides` object. Its rules are merged into that integration's config, so they apply to the same files (for example, `vue.overrides` only applies to `.vue` files). See [Rules & renaming](https://vinicunca.dev/eslint/configuration/rules-overrides) for all the ways to change rules.

The first argument is meant for **global** options, so it has two special cases:

- `ignores` extends the global ignore list instead of acting like a flat config `ignores`. Pass an array to add globs, or a function to edit the defaults.
- `files` is not allowed. The factory throws an error if you pass it; put file-scoped rules in a later argument instead.

The first argument also accepts these flat config properties: `name`, `languageOptions`, `linterOptions`, `processor`, `plugins`, `rules` and `settings`. They are collected into one extra config item placed after the generated configs and before your extra configs.

```js [eslint.config.js]
import { vinicuncaESLint } from '@vinicunca/eslint-config';

export default vinicuncaESLint({
  vue: true,
  rules: {
    'no-console': 'off',
  },
});
```

The [options reference](https://vinicunca.dev/eslint/configuration/options) lists every option with its type and default.

## Generated configs

The factory builds a list of named config items. Each name starts with `vinicunca/`, which is what you pass to composer methods such as `.override()`. With the defaults, the order is:

1. `vinicunca/gitignore`, `vinicunca/ignores`
2. `vinicunca/javascript/*`, `vinicunca/eslint-comments/rules`, `vinicunca/command/rules`
3. `vinicunca/perfectionist/rules`, `vinicunca/node/rules`, `vinicunca/jsdoc/*`, `vinicunca/imports/rules`, `vinicunca/e18e/rules`, `vinicunca/unicorn/*`, `vinicunca/jsx/setup`
4. `vinicunca/typescript/*`, then `vinicunca/antislop/*` (on by default)
5. `vinicunca/stylistic/rules`, `vinicunca/regexp/rules`, `vinicunca/test/*`
6. Framework configs: `vinicunca/vue/*`, `vinicunca/react/*`, `vinicunca/nextjs/*`, `vinicunca/solid/*`, `vinicunca/svelte/*`, `vinicunca/unocss`, `vinicunca/astro/*`
7. `vinicunca/jsonc/*`, `vinicunca/sort/package-json`, `vinicunca/sort/tsconfig`, `vinicunca/pnpm/*`, `vinicunca/yaml/*`, `vinicunca/toml/*`, `vinicunca/markdown/*`
8. `vinicunca/formatter/*` when [formatters](https://vinicunca.dev/eslint/configuration/formatters) are enabled
9. `vinicunca/disables/*`: relaxed rules for `scripts/`, `cli/`, `bin/`, `*.d.ts`, `*.js`/`*.cjs` and `*.config.*` files

Your extra configs come after all of these, so they win when they set the same rule. Use the [config inspector](https://vinicunca.dev/eslint/guides/config-inspector) to see the exact list for your project.

## Composer API

`vinicuncaESLint()` returns a `FlatConfigComposer` from [eslint-flat-config-utils](https://github.com/antfu/eslint-flat-config-utils). Its methods are chainable and are resolved when ESLint loads the config:

- `.append(...configs)` / `.prepend(...configs)`: add configs at the end or the start.
- `.insertBefore(name, ...configs)` / `.insertAfter(name, ...configs)`: add configs next to a named config.
- `.override(name, config)`: merge into a named config, or pass a function that receives and returns it. `.overrides({ [name]: config })` does several at once.
- `.overrideRules(rules)`: change rule entries everywhere they are configured.
- `.remove(name)` / `.replace(name, ...configs)`: drop or swap a named config.
- `.removeRules(...ruleIds)` / `.removePlugins(...names)`: strip rules or plugins from every config.
- `.renamePlugins(map)`: rename plugin prefixes in every config.
- `.disableRulesFix(ruleIds, options)`: keep rules reporting but make them non-fixable.
- `.onResolved(callback)`: inspect or edit the final array.
- `.toConfigs()`: resolve to a plain `Linter.Config[]`.

```js [eslint.config.js]
import { vinicuncaESLint } from '@vinicunca/eslint-config';

export default vinicuncaESLint()
  .insertAfter('vinicunca/javascript/rules', {
    name: 'my-project/legacy',
    files: ['legacy/**/*.js'],
    rules: {
      'no-var': 'off',
    },
  })
  .overrideRules({
    'no-console': ['error', { allow: ['info', 'warn', 'error'] }],
  })
  .remove('vinicunca/sort/tsconfig');
```

## Typed configs

The package exports its types, so you get autocompletion for options and rule names in `eslint.config.ts` or with JSDoc:

```ts [eslint.config.ts]
import type { TypedFlatConfigItem } from '@vinicunca/eslint-config';
import { vinicuncaESLint } from '@vinicunca/eslint-config';

const legacy: TypedFlatConfigItem = {
  files: ['legacy/**/*.js'],
  rules: {
    'no-var': 'off',
  },
};

export default vinicuncaESLint({ type: 'app' }, legacy);
```

Useful exports include `OptionsConfig` (the options type), `TypedFlatConfigItem`, `ConfigNames` (every generated config name) and `Rules`.

## Building your own composition

Each integration is also exported as a function (`javascript`, `typescript`, `stylistic`, `vue`, `jsonc`, `markdown` and so on), together with helpers such as `combine`, `renameRules`, `renamePluginInConfigs` and the `GLOB_*` constants. You can compose them by hand when you need full control:

```js [eslint.config.js]
import {
  combine,
  comments,
  ignores,
  imports,
  javascript,
  jsdoc,
  jsonc,
  markdown,
  node,
  sortPackageJson,
  sortTsconfig,
  stylistic,
  toml,
  typescript,
  unicorn,
  vue,
  yaml,
} from '@vinicunca/eslint-config';

export default combine(
  ignores(),
  javascript(),
  comments(),
  node(),
  jsdoc(),
  imports(),
  unicorn(),
  typescript(),
  stylistic(),
  vue({ typescript: true }),
  jsonc(),
  sortPackageJson(),
  sortTsconfig(),
  yaml(),
  toml(),
  markdown(),
);
```

> [!WARNING]
> 
> Hand-composed configs skip what the factory does for you: auto-detection, sharing stylistic options between integrations, editor detection, plugin renaming of your own configs and the composer API. Prefer the factory unless you have a specific reason not to.

## In this section

[**Options**](https://vinicunca.dev/eslint/configuration/options)

Every option with its type and default.

[**Frameworks**](https://vinicunca.dev/eslint/configuration/frameworks)

Vue, React, Next.js, Svelte, Solid, Astro and UnoCSS.

[**Formatters**](https://vinicunca.dev/eslint/configuration/formatters)

Format CSS, HTML, XML, SVG, Markdown, GraphQL and Astro files.

[**TypeScript**](https://vinicunca.dev/eslint/configuration/typescript)

TypeScript support, type-aware rules and erasable-syntax-only mode.

[**Rules & renaming**](https://vinicunca.dev/eslint/configuration/rules-overrides)

Override rules and understand the renamed plugin prefixes.

[**Optional configs**](https://vinicunca.dev/eslint/configuration/optional-configs)

Anti-slop, pnpm workspace, e18e, regexp and command rules.


## Sitemap

See the full [sitemap](https://vinicunca.dev/sitemap.md) for all pages.
