@anolilab/eslint-config
TypeScript icon, indicating that this package has built-in type declarations

16.2.4 • Public • Published

Shareable ESLint config

typescript-image npm-image license-image


Daniel Bannert's open source work is supported by the community on GitHub Sponsors


Purpose

Our package serves as a valuable resource for JavaScript/Typescript-based projects, offering composable ESLint configurations. It encompasses a range of features, including performance optimization and the flexibility to extend pre-defined base configurations. We aim to provide a strong, opinionated foundation for code quality and consistency, while still allowing for customization to suit specific project needs.

  • Tailored Configuration for Workspaces: With this package, each workspace within your monorepo gains the ability to have its own customized ESLint configuration. This ensures that individual projects can maintain their specific requirements while still adhering to the overall guidelines.

  • Configurability at Your Fingertips: Crafting your workspace's ESLint configuration is a breeze, thanks to the seamless composition of pre-defined base configurations. This empowers you to tailor the settings to suit your project's unique needs, without starting from scratch.

  • Enhanced Efficiency: We've optimized the package's performance by intelligently enabling plugins based on file naming conventions and project dependencies. This streamlined approach ensures that your ESLint checks run efficiently, targeting the relevant files and maximizing productivity.

[!NOTE] Since v16.0.0, this config is rewritten to the new ESLint Flat config.

ESLint v9.5.0+ is now required.

[!WARNING]

Please keep in mind that this is still a personal config with a lot of opinions. Changes might not always work for everyone and every use case.

If you are using this config directly, I suggest you review the changes every time you update. Or if you want more control over the rules, always feel free to fork it. Thanks!

Highlights

  • Zero-config for many common setups, but highly configurable when needed.
  • Enforces readable and consistent code, because you read more code than you write.
  • Lints a wide range of files, including JavaScript, TypeScript, JSON, YAML, Markdown, and more.
  • No need to specify file paths to lint as it intelligently lints relevant files, respecting .gitignore and common ignore patterns.
  • Config overrides per files/globs.
  • First-class TypeScript support, automatically enabled if typescript is detected in your project.
  • Includes a comprehensive set of ESLint plugins, like unicorn, import, sonarjs, and security plugins. (See more under Plugins).
  • Automatically enables relevant rules based on the engines field in your package.json.
  • Easily configure stylistic preferences like indent and semicolon without deep diving into rule configurations.
  • Works alongside Prettier: Our configuration disables ESLint rules that would conflict with Prettier, allowing ESLint to focus on code quality and Prettier on formatting if you choose to use both. However, many stylistic rules are included and can be enforced by ESLint directly.

Install

To install this config, run the following command.

npm install --save-dev eslint @anolilab/eslint-config
pnpm add -D eslint @anolilab/eslint-config
yarn add -D eslint @anolilab/eslint-config

Usage

Our default export is designed to be used within ESLint's flat configuration system (e.g., eslint.config.js). It contains a comprehensive set of ESLint rules, suitable for modern ECMAScript (ES2021+ by default) and TypeScript projects.

To use it, import the createConfig function from @anolilab/eslint-config into your eslint.config.js (or eslint.config.mjs). This function allows you to generate the configuration, optionally with your own settings.

Create eslint.config.mjs in your project root:

// eslint.config.mjs

import { createConfig } from "@anolilab/eslint-config";

export default createConfig();
Combined with legacy config:

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 { createConfig } from "@anolilab/eslint-config";
import { FlatCompat } from "@eslint/eslintrc";

const compat = new FlatCompat();

export default createConfig(
    {
        ignores: [],
    },

    // Legacy config
    ...compat.config({
        extends: [
            "eslint:recommended",
            // Other extends...
        ],
    }),

    // Other flat configs...
);

Note that .eslintignore no longer works in Flat config.

Or you can configure each integration individually, for example:

// eslint.config.js
import { createConfig } from "@anolilab/eslint-config";

export default createConfig({
    // Enable stylistic formatting rules
    // stylistic: true,

    // `.eslintignore` is no longer supported in Flat config, use `ignores` instead
    ignores: [
        "**/fixtures",
        // ...globs
    ],

    // Disable jsonc and yaml support
    jsonc: false,
    // 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,

    yaml: false,
});

Add script for package.json

For example:

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

The factory function also accepts any number of arbitrary custom config overrides:

// eslint.config.js
import { createConfig } from "@anolilab/eslint-config";

export default createConfig(
    {
        // Configures for anolilab's config
    },

    // From the second arguments they are ESLint Flat Configs
    // you can have multiple configs
    {
        files: ["**/*.ts"],
        rules: {},
    },
    {
        rules: {},
    },
);

We also provided the overrides options in each integration to make it easier:

// eslint.config.js
import { createConfig } from "@anolilab/eslint-config";

export default createConfig({
    typescript: {
        overrides: {
            "ts/consistent-type-definitions": ["error", "interface"],
        },
    },
    yaml: {
        overrides: {
            // ...
        },
    },
});

IDE Support (auto fix on save)

🟦 VS Code support

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"
    },

    // Silent the stylistic rules in you IDE, 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",
        "jsonc",
        "yaml",
        "toml",
        "xml",
        "gql",
        "graphql",
        "astro",
        "svelte",
        "css",
        "less",
        "scss",
        "pcss",
        "postcss"
    ]
}
🟩 Neovim Support

Update your configuration to use the following:

local 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 },
}

local lspconfig = require('lspconfig')
-- Enable eslint for all supported languages
lspconfig.eslint.setup(
  {
    filetypes = {
      "javascript",
      "javascriptreact",
      "javascript.jsx",
      "typescript",
      "typescriptreact",
      "typescript.tsx",
      "vue",
      "html",
      "markdown",
      "json",
      "jsonc",
      "yaml",
      "toml",
      "xml",
      "gql",
      "graphql",
      "astro",
      "svelte",
      "css",
      "less",
      "scss",
      "pcss",
      "postcss"
    },
    settings = {
      -- Silent the stylistic rules in you IDE, but still auto fix them
      rulesCustomizations = customizations,
    },
  }
)

Neovim format on save

There's few ways you can achieve format on save in neovim:

  • nvim-lspconfig has a EslintFixAll command predefined, you can create a autocmd to call this command after saving file.
lspconfig.eslint.setup({
  --- ...
  on_attach = function(client, bufnr)
    vim.api.nvim_create_autocmd("BufWritePre", {
      buffer = bufnr,
      command = "EslintFixAll",
    })
  end,
})

Using getFilesGlobs for Common File Types

Your @anolilab/eslint-config package also exports a handy utility function getFilesGlobs that provides pre-defined glob patterns for common file types. This can simplify targeting specific sets of files in your ESLint configuration objects.

You can import it alongside createConfig:

// eslint.config.js
import { createConfig, getFilesGlobs } from "@anolilab/eslint-config";

const baseConfig = createConfig();

// Get glob patterns for all JavaScript and TypeScript files
const jsTsFiles = getFilesGlobs("js_and_ts");
// Get glob patterns for Markdown files
const markdownFiles = getFilesGlobs("markdown");
// Get glob patterns for HTML related files
const htmlFiles = getFilesGlobs("html");

export default [
    ...baseConfig,
    {
        files: jsTsFiles,
        // languageOptions, rules, etc., specific to JS and TS files
        rules: {
            // 'your-rule/for-js-ts': 'error',
        },
    },
    {
        files: markdownFiles,
        // languageOptions, rules, etc., specific to Markdown files
        // Often, you might use a specific processor or plugin for Markdown here
        // processor: markdownProcessor, // Fictional example
        // plugins: { markdownPlugin } // Fictional example
    },
    {
        files: htmlFiles,
        // languageOptions, rules, etc., specific to HTML files
    },
    // ... other configurations
];

Type Aware Rules

You can optionally enable the type aware rules by passing the options object to the typescript config:

// eslint.config.js
import antfu from "@antfu/eslint-config";

export default antfu({
    typescript: {
        tsconfigPath: "tsconfig.json",
    },
});

Utilities

The getFilesGlobs function accepts one of the following FileType strings:

  • "all": All JavaScript, TypeScript, and declaration files.
  • "astro_ts": TypeScript files within Astro components.
  • "astro": Astro component files (.astro).
  • "css": CSS files.
  • "types": TypeScript declaration files (.d.ts, .d.cts, .d.mts).
  • "e2e": End-to-end test files.
  • "graphql": GraphQL files (.gql, .graphql).
  • "html": Various HTML-like template files (.html, .hbs, .erb, etc.).
  • "js_and_ts": All JavaScript and TypeScript source files (excluding declarations).
  • "js": JavaScript files (.js, .mjs, .cjs).
  • "jsx_and_tsx": JSX and TSX files.
  • "less": LESS files.
  • "markdown_in_markdown": Markdown files embedded within other Markdown files.
  • "markdown_inline_js_jsx": JS/JSX code blocks within Markdown.
  • "markdown": Markdown files (.md, .mkdn, etc.).
  • "postcss": PostCSS configuration files.
  • "scss": SCSS files.
  • "storybook": Storybook story files.
  • "svg": SVG files.
  • "toml": TOML files.
  • "ts": All TypeScript files including declarations and TSX (.ts, .tsx, .d.ts, etc.).
  • "vitest": Vitest test files.
  • "xml": XML files.
  • "yaml": YAML files (.yaml, .yml).

Using getFilesGlobs can make your configuration more readable and maintainable by abstracting away the specific glob patterns.

Plugins

Our configuration integrates a wide array of ESLint plugins to cover various aspects of code quality, language support, security, and specific libraries/frameworks. Many of these are enabled automatically when relevant dependencies are detected in your project.

Core & Code Quality

These plugins form the backbone of our linting rules, focusing on best practices, consistency, and potential errors.

Stylistic & Formatting

These plugins help maintain a consistent code style. Note that while these are included, you can also use Prettier for formatting, and our config is designed to be compatible.

Language Support & Syntax

Plugins for specific languages or syntaxes beyond standard JavaScript/TypeScript.

Import & Module System

Managing imports and module structure.

  • eslint-plugin-import-x (formerly eslint-plugin-import): Linting of ES2015+ (ES6+) import/export syntax, and prevent issues with misspelling of file paths and import names.
    • Uses eslint-import-resolver-node and eslint-import-resolver-typescript.
  • eslint-plugin-n (formerly eslint-plugin-node): Additional ESLint rules for Node.js.

Security

Plugins focused on identifying potential security vulnerabilities.

Testing

Plugins for various testing frameworks and practices.

Frameworks & Libraries

Support for specific UI frameworks, libraries, and tools.

Documentation & Comments

Compatibility & Others


List of Used Plugins (Condensed)

This list is a more condensed version and might not be exhaustive if some plugins are very specific or utility-based. It aims to provide a quick overview of the primary active linting plugins.

  • @eslint/js
  • @stylistic/eslint-plugin
  • @typescript-eslint/eslint-plugin
  • @eslint-community/eslint-plugin-eslint-comments
  • @eslint-react/eslint-plugin
  • @tanstack/eslint-plugin-query
  • @tanstack/eslint-plugin-router
  • @unocss/eslint-plugin
  • eslint-plugin-antfu
  • eslint-plugin-astro
  • eslint-plugin-compat
  • eslint-plugin-es-x
  • eslint-plugin-format
  • eslint-plugin-html (or @html-eslint/eslint-plugin)
  • eslint-plugin-import-x
  • eslint-plugin-jsdoc
  • eslint-plugin-jsonc
  • eslint-plugin-jsx-a11y
  • eslint-plugin-n
  • eslint-plugin-no-only-tests
  • eslint-plugin-no-secrets
  • eslint-plugin-no-unsanitized
  • eslint-plugin-perfectionist
  • eslint-plugin-playwright
  • eslint-plugin-promise
  • eslint-plugin-react-hooks
  • eslint-plugin-regexp (often a dependency of other plugins like SonarJS)
  • eslint-plugin-security
  • eslint-plugin-simple-import-sort
  • eslint-plugin-sonarjs
  • eslint-plugin-storybook
  • eslint-plugin-tailwindcss
  • eslint-plugin-testing-library
  • eslint-plugin-toml
  • eslint-plugin-tsdoc
  • eslint-plugin-unicorn
  • eslint-plugin-unused-imports
  • eslint-plugin-yml
  • eslint-plugin-zod
  • eslint-plugin-you-dont-need-lodash-underscore

Our Stance on Formatting

This ESLint configuration includes stylistic rules that can format your JavaScript and TypeScript code, promoting consistency.

  • ESLint as the Primary Tool: For JS/TS files, we encourage using ESLint for both linting code quality and enforcing code style. The VSCode settings above are configured to use ESLint as the default formatter for these files.
  • Working with Prettier: If you use Prettier in your project, this config is designed to be compatible. It disables ESLint rules that would conflict with Prettier's formatting decisions. You can let Prettier handle formatting for files ESLint doesn't cover (like CSS, HTML, etc.), or even use Prettier for JS/TS formatting and then have ESLint apply further fixes. However, for a streamlined experience with JS/TS, letting ESLint handle all aspects (quality and style) is often simpler.

Lint Staged / Pre-commit Hooks

To ensure code is linted and fixed before committing, we recommend integrating with a pre-commit tool like lint-staged and husky. Our sister package, @anolilab/lint-staged-config, is designed to work seamlessly with this ESLint configuration.

Example lint-staged configuration in your package.json (or relevant file):

// package.json
{
    "lint-staged": {
        "*.{js,jsx,ts,tsx}": "eslint --fix"
        // Add other linters for other file types if needed
    }
}

Ensure husky is set up to run lint-staged on pre-commit.

Versioning Policy

This project aims to follow Semantic Versioning.

  • Major versions: May include breaking changes to ESLint configurations, Node.js version support, or significant plugin changes.
  • Minor versions: May introduce new non-breaking rules, enable new plugins by default (if non-breaking), or update existing rules with new options.
  • Patch versions: Typically include bug fixes or minor tweaks to rule configurations.

Changes to rule strictness (e.g., changing a 'warn' to an 'error') might occur in minor versions if they reflect evolving best practices. We recommend reviewing changes when updating.

Q & A

Why not standard

The standard specification believes that everyone should not waste time in personalized specifications, but the entire community should unify a specification. This statement makes sense, but it runs against the ESLint's design philosophy. Don't you remember how ESLint defeated JSHint and became the most popular JS code inspection tool? It's because of the plugin and configuration that ESLint advocates, which meets the individual needs of different technology stacks of different teams.

Therefore, @anolilab/eslint-config also inherits the philosophy of ESLint. It will not force you to use our config.

Supported Node.js Versions

Libraries in this ecosystem make the best effort to track Node.js' release schedule. Here's a post on why we think this is important.

Contributing

If you would like to help take a look at the list of issues and check our Contributing guild.

Note: please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

Credits

License

The anolilab javascript-style-guide is open-sourced software licensed under the MIT license

Package Sidebar

Install

npm i @anolilab/eslint-config

Weekly Downloads

1,660

Version

16.2.4

License

MIT

Unpacked Size

2.41 MB

Total Files

11

Last publish

Collaborators

  • prisis