Migrating

Upgrade from v5 to v6, or switch from Prettier or another ESLint config to @vinicunca/eslint-config.

Upgrading from v5 to v6

v6 drops ESLint 9 and turns on the anti-slop rules by default.

Upgrade ESLint to v10

The eslint peer range is now ^10.0.0. ESLint 9 is no longer supported. Follow the ESLint v10 migration guide, which also lists the supported Node.js versions.

pnpm add -D eslint@^10 @vinicunca/eslint-config@^6

Remove the anti-slop plugins from your dependencies

eslint-plugin-slop and eslint-plugin-sonarjs are now regular dependencies of the config. If you installed them only for this config (or for the v5.7.1 Cannot find package 'eslint-plugin-sonarjs' error), remove them:

pnpm remove eslint-plugin-slop eslint-plugin-sonarjs

Decide on anti-slop

antislop now defaults to true, so expect new reports from slop/no-em-dash, the curated sonarjs/* rules and sonarjs/cognitive-complexity (threshold 15). Keep them, tune them, or turn them off:

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

export default vinicuncaESLint({
  // Turn everything off
  antislop: false,

  // ...or keep it and tune it
  // antislop: { cognitiveComplexity: 25, slop: false },
});

slop/no-em-dash now runs on every file type the config lints, including YAML and Markdown prose. In v5 it only covered source, JSONC, TOML and GraphQL files.

Check your Markdown options

In v5 the factory ignored markdown.gfm and markdown.overridesMarkdown, so only markdown.overrides had any effect. v6 forwards them all. If you set gfm: false or overridesMarkdown, they now apply. Remove them if you relied on the old behavior.

Fix the repo once

pnpm eslint --fix

Review the remaining reports, mostly from the anti-slop rules.

Other fixes in v6:

  • typescript.erasableOnly now applies only to TypeScript files (and the files you pass in typescript.files), including component scripts and TypeScript code blocks in Markdown. Before, it also ran on JavaScript files and Markdown prose.

From Prettier

This config formats JavaScript, TypeScript, Vue, JSON, YAML, TOML and Markdown code blocks with ESLint. Use formatters for CSS, HTML, XML, GraphQL and Astro instead of a separate Prettier CLI.

Install ESLint and the config

pnpm add -D eslint @vinicunca/eslint-config

Add eslint.config.js

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

export default vinicuncaESLint({
  formatters: {
    css: true,
    html: true,
  },
});

Drop formatters if you only care about JS/TS/Vue. Enable more languages as needed.

Point the editor at ESLint

Use the VS Code settings: "prettier.enable": false, "editor.formatOnSave": false, and source.fixAll.eslint on save.

Remove Prettier from JS/TS

Uninstall prettier, eslint-config-prettier and eslint-plugin-prettier if they were only formatting application code. Keep Prettier only if a formatters.* option needs a plugin (for example @prettier/plugin-xml).

Delete .prettierrc* and Prettier entries in package.json. ESLint Stylistic does not read Prettier config files.

Fix the repo once

pnpm eslint --fix

Review the diff: semicolons are on, arrow parameters are always parenthesized, and imports are sorted.

From antfu/eslint-config

  1. Replace the package with @vinicunca/eslint-config.
  2. Change import antfu from '@antfu/eslint-config' to import { vinicuncaESLint } from '@vinicunca/eslint-config'.
  3. Call vinicuncaESLint(...) instead of antfu(...).
  4. Replace composer names antfu/ with vinicunca/.
  5. Expect style churn: semicolons, 1tbs braces in JS/TS, always-parens arrows. lessOpinionated will not relax rules.
  6. There is no CLI wizard and no angular option.

See Differences from antfu/eslint-config.

From eslint-config-airbnb, Standard, or extends

Flat config does not use extends from .eslintrc. Delete .eslintrc* and .eslintignore (use ignores in the factory). Start from vinicuncaESLint() and re-apply only the rules you still need as extra configs.

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

export default vinicuncaESLint(
  {
    ignores: ['legacy/**'],
  },
  {
    files: ['legacy/**/*.js'],
    rules: {
      'no-var': 'off',
    },
  },
);

To reuse an old eslintrc snippet, wrap it with @eslint/eslintrc FlatCompat and pass the result as a later argument — prefer rewriting to flat configs when you can.

Git hooks

Keep lint-staged running eslint --fix on *. You no longer need prettier --write in that hook for files ESLint already formats.