Introduction

GitHubnpm
Install @vinicunca/eslint-config, a flat ESLint config that lints and formats JavaScript, TypeScript, Vue and more in one call.

@vinicunca/eslint-config is Vinicunca's shareable flat config for ESLint. It lints and formats your code, so you don't need Prettier for JavaScript, TypeScript, Vue, JSON, YAML, TOML or Markdown.

This config is a fork of antfu/eslint-config. Most integrations and plugins come from Anthony Fu's work; this fork changes the code style and some defaults. See Differences from antfu/eslint-config.

Features

  • One call: vinicuncaESLint() returns a complete flat config with sensible defaults.
  • Formatting without Prettier: powered by ESLint Stylistic, with auto-fix for everything.
  • Code style: 2-space indent, single quotes, semicolons, } else { on one line, braces around every block, parentheses around arrow parameters, trailing commas, sorted imports and exports.
  • Auto-detected: TypeScript (when typescript is installed), Vue (when vue, nuxt, vitepress or @slidev/cli is installed) and pnpm workspace rules (when a pnpm-workspace.yaml exists).
  • On by default: JSON, JSONC, JSON5, YAML, TOML, Markdown (including code blocks), test files (via the Vitest plugin), Node.js, JSDoc, regular expressions, e18e modernization rules and anti-slop rules.
  • Opt-in: React, Next.js, Svelte, Solid, Astro and UnoCSS, external formatters for CSS/HTML/XML/GraphQL and type-aware rules.
  • Respects .gitignore by default.
  • Requires ESLint ^10.0.0. Upgrading from v5? See Upgrading to v6.

Installation

pnpm add -D eslint @vinicunca/eslint-config

Framework integrations need their own plugins (for example eslint-plugin-svelte for Svelte). When you run ESLint in an interactive terminal, the config asks to install any missing plugin for the options you enabled. Each framework section lists the exact packages.

Usage

Create eslint.config.js in your project root:

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

export default vinicuncaESLint();
vinicuncaESLint is a named export; the package has no default export. If your package.json does not set "type": "module", name the file eslint.config.mjs. You can also write eslint.config.ts for typed options.

Pass options to tune the integrations, and extra flat configs to add your own rules:

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

export default vinicuncaESLint(
  {
    type: 'lib',
    ignores: ['**/fixtures'],
    vue: { a11y: true },
  },
  {
    files: ['**/*.ts'],
    rules: {
      'ts/no-explicit-any': 'error',
    },
  },
);

See Configuration for how options and extra configs combine, and the options reference for every option.

Scripts

Add lint scripts to package.json:

package.json
{
  "scripts": {
    "lint": "eslint",
    "lint:fix": "eslint --fix"
  }
}

Then run them with your package manager:

pnpm lint
pnpm lint:fix
Use pnpm eslint (or npx eslint) to run the ESLint binary installed in your project. pnpx eslint / pnpm dlx eslint downloads a separate copy that can't see your local config dependencies.

Editor setup

VS Code

Install the ESLint extension, then add the following to .vscode/settings.json:

.vscode/settings.json
{
  // Disable the default formatter, use ESLint instead
  "prettier.enable": false,
  "editor.formatOnSave": false,

  // Auto fix on save
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit",
    "source.organizeImports": "never"
  },

  // Silence the stylistic rules in the editor, but still auto fix them
  "eslint.rules.customizations": [
    { "rule": "style/*", "severity": "off", "fixable": true },
    { "rule": "format/*", "severity": "off", "fixable": true },
    { "rule": "*-indent", "severity": "off", "fixable": true },
    { "rule": "*-spacing", "severity": "off", "fixable": true },
    { "rule": "*-spaces", "severity": "off", "fixable": true },
    { "rule": "*-order", "severity": "off", "fixable": true },
    { "rule": "*-dangle", "severity": "off", "fixable": true },
    { "rule": "*-newline", "severity": "off", "fixable": true },
    { "rule": "*quotes", "severity": "off", "fixable": true },
    { "rule": "*semi", "severity": "off", "fixable": true }
  ],

  // Enable ESLint for all supported languages
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact",
    "vue",
    "html",
    "markdown",
    "json",
    "json5",
    "jsonc",
    "yaml",
    "toml",
    "xml",
    "gql",
    "graphql",
    "astro",
    "svelte",
    "css",
    "less",
    "scss",
    "pcss",
    "postcss"
  ]
}

source.organizeImports is turned off because import sorting is handled by the perfectionist/sort-imports rule.

Editor-specific behavior

The config detects when ESLint runs inside an editor (VS Code, JetBrains IDEs, Vim, Neovim or Zed) and makes three rules non-fixable there, so saving a file doesn't delete code you are still working on:

These rules still report problems (as warnings in the editor), and they are fixed normally when you run ESLint from the terminal, in CI or in a git hook. To turn this behavior off, pass isInEditor: false:

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

export default vinicuncaESLint({
  isInEditor: false,
});

Git hooks

To lint and fix staged files before every commit, use lint-staged with simple-git-hooks:

pnpm add -D lint-staged simple-git-hooks
package.json
{
  "simple-git-hooks": {
    "pre-commit": "pnpm lint-staged"
  },
  "lint-staged": {
    "*": "eslint --fix"
  }
}

Then register the hook once:

# Activate the hooks
pnpm simple-git-hooks

Editor detection is skipped inside git hooks and lint-staged, so every fix is applied on commit.

Next steps

Configuration

Learn how options, extra configs and the composer API fit together.

Options reference

Every option, with its type and default.

Frameworks

Enable Vue, React, Next.js, Svelte, Solid, Astro or UnoCSS.

Agent skill

Conventions for AI agents writing code linted by this config.