npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

eslint-kit

v11.30.0

Published

All-in-one solution for configuring ESLint in all of your projects

Downloads

7,567

Readme

Before you start

The README on main branch can contain some unreleased changes.

Go to release/latest branch to see the actual README for the latest version from NPM.

Previous releases

Navigation

Why?

  • Most configs contain too common rules inside, so you need to do a lot of things to finalize them for your project.
  • You have to update config dependencies manually.
  • The other configs are bound to a specific stack/technology, so it's hard to extend them in a way that you like.
  • Sometimes, configs use formatting rules. Formatting is not ESLint's job, so there's a high chance to get into a conflict someday.
  • Together, the above means that most likely you'll need a different ESLint config for each of your projects.
  • You may often need to install a lot of dependencies: eslint, prettier, plugins, configs, parser, etc.
  • You may often face problems with eslint/parser/plugin/config versions. It takes time to find the issue and solution.
  • The average ESLint config UX is poor - for example, when using no-console rule, you will get warnings during the development. This kind of checks is useful when linting code for the production (CI environment, precommit hooks), but useless in development. ESLint Kit has allowDebug option to solve this problem.

ESLint Kit is solving all these problems by providing many small presets, each performing a specific task.

You can select presets by using configure function in your .eslintrc.cjs file:

const { configure, presets } = require('eslint-kit')

module.exports = configure({
  mode: 'only-errors',
  presets: [
    presets.imports(),
    presets.typescript(),
    presets.prettier(),
    presets.node(),
    presets.react({ version: '18.0' }),
  ],
  extend: {
    rules: {
      'some-rule': 'off'
    }
  }
})

eslint-kit dependencies are automatically updated. The configs are covered with tests, and each package update is tested. Broken plugins/rules/configs will not be deployed and will stuck at the review process, waiting for the fix by a developers.

eslint-kit package contains all the dependencies you might need. The only exception are eslint and prettier - they should be installed separately to work properly (executing yarn eslint and so on).

The ESLint Kit presets try to contain only the best-practice rules to make overwriting as rare as possible. But you can still easily override them by using extend property.

Quick installation

npx eslint-kit-cli@latest

Or if you want to use exactly 11 version of eslint-kit:

npx eslint-kit-cli@^11

Learn more about eslint-kit-cli

Manual installation

NPM:

npm install -D eslint-kit@^11.0.0 eslint@^8.57.0 prettier@^3.0.0

Yarn:

yarn add -D eslint-kit@^11.0.0 eslint@^8.57.0 prettier@^3.0.0

After installing, add the .eslintrc.cjs file in your project root:

const { configure, presets } = require('eslint-kit')

module.exports = configure({
  presets: [],
})

Now, just select the presets you need. The full information about them is located in Presets section.

You can also set up your editor if you haven't already.

configure API

configure({
  // (optional) Project root
  root: __dirname,

  // (optional) Base ESLint Config to extend from
  // May be used in monorepos to declare shared ESLint Kit options for all packages
  // See "Extends" section for more info
  extends: '../../base.eslintrc.cjs',
  // Also accepts ESLint Config object, but only if it was created using ESLint Kit
  extends: require(path.resolve(__dirname, '../../base.eslintrc.cjs')),
  
  // (optional) Allow debug
  // Very good option for development
  // See "Allow Debug" section for more info
  allowDebug: false,

  // (optional) Mode
  // See "Linting Modes" section for more info 
  mode: 'default',

  // (optional) ESLint Kit presets
  presets: [],

  // (optional) Custom eslint config
  // It gets merged with presets at the end
  extend: { rules: { /* ... */ } }
})

Presets

Common

  • Enables unicorn, 'sonarjs', and @stylistic/eslint-plugin plugins
  • Enables @babel/eslint-parser
  • Adds commonly used JavaScript rules
  • No need to include it in presets manually
  • Enables import-x and simple-import-sort plugins
  • Enables alias support for jsconfig and tsconfig
  • Configures file extensions depending on used presets
configure({
  presets: [
    presets.imports({
      // (optional) Imports sort settings
      sort: {
        // (optional) Add newline between import groups
        newline: false,

        // (optional) Define groups for sorting (see below)
        groups: [/* ... */]
      },

      // (optional) Alias settings
      alias: {
        // (optional) Base path for all aliases
        // Defaults to './'
        root: './src',

        // (optional) Aliases
        // Defaults to empty object
        paths: { '@app': './' },

        // (optional) A custom path to jsconfig
        // Defaults to jsconfig.json
        jsconfig: 'jsconfig.json'
      }
    })
  ]
})

Under the hood, we use eslint-plugin-simple-import-sort. It provides an option to override sorting groups - check out this section in their README.

These are the default groups values used by eslint-kit:

[
  // side effects
  ['^\\u0000'],

  // node.js libraries and scoped libraries
  ['^(child_process|crypto|events|fs|http|https|os|path)(/.*)?$', '^@?\\w'],

  // common aliases (@app, @root, @/, ~/) and anything not matched
  ['^@app', '^@root', '^~', '^'],

  // relative imports
  ['^\\.'],
]

To define your own groups, just pass it inside using sort.groups.

  • Changes parser to @typescript-eslint/parser
  • Allows the usage of .ts, .mts and .tsx extensions
  • Adds some TypeScript-specific rules (for TS files)
  • Replaces some default ESLint rules with their TypeScript analogues (for TS files)
configure({
  presets: [
    presets.typescript({
      // (optional) Project's root
      root: './',

      // (optional) A path to tsconfig file
      tsconfig: 'tsconfig.json',

      // (optional) Enforce using `type` insead of `interface`
      // Default to `false` in v11, will become `true` in v12, and will be removed in v13
      // ESLint Kit CLI will set `true` on bootstrap
      enforceUsingType: false,
    })
  ]
})
  • Enables the rule prettier/prettier from Prettier ESLint plugin
configure({
  presets: [
    /*
     * Optionally, you can pass the Prettier config
     * Note: it will merge and override any options set with .prettierrc files
     */
    presets.prettier({
      semi: false,
      singleQuote: true
      // ...
    })
  ]
})

The recommended Prettier config:

{
  "semi": false,
  "singleQuote": true,
  "tabWidth": 2,
  "quoteProps": "consistent"
}
  • Enables node environment
configure({
  presets: [presets.node()]
})

Frameworks

  • Adds some React and React Hooks rules
  • Enables browser environment and jsx ecma feature
configure({
  presets: [
    presets.react({
      // (optional) Allows to specify React version
      version: 'detect',
      // (optional) Allows using JSX without importing `React`
      newJSXTransform: false
    })
  ]
})
  • Adds vue plugin
  • Changes parser to vue-eslint-parser
  • Detects installed vue version and enables /recommended rules for it
  • Enables @typescript-eslint/parser for <script> blocks when typescript preset is used
  • Enables browser environment and jsx ecma feature
  • Allows export default

You still need to set up your editor / IDE to lint .vue files. You can use this guide from Vue documentation.

configure({
  presets: [
    presets.vue({
      // (optional) Allows to specify Vue version
      version: 'detect'
    })
  ]
})
  • Adds astro plugin
  • Uses parser to astro-eslint-parser for .astro files
  • Enables /recommended rules and environment for Astro
  • Enables @typescript-eslint/parser for <script> tags when typescript preset is used

You still need to set up your editor / IDE to lint .astro files. You can use this guide from Astro documentation.

configure({
  presets: [presets.astro()]
})

If you use Prettier, you also need to install prettier-plugin-astro. Use this guide from plugin documentation.

  • Adds solid plugin and enables /recommended rules
  • Enables /typescript rules when typescript preset is active
configure({
  presets: [presets.solidJs()]
})
  • Adds svelte3 plugin and configures it
  • Enables some TypeScript settings when typescript preset is active

You still need to set up your editor / IDE to lint .svelte files. You can use this guide from svelte3 plugin repo.

configure({
  presets: [
    presets.svelte({
      // (optional) Disable type checking for .svelte files
      noTypeCheck: true
    })
  ]
})
  • Enables @next/eslint-plugin-next plugin rules
  • Enables new JSX transform support
  • Allows the usage of export default

nextJs preset doesn't provide React rules, so don't forget to add react preset too. You may omit newJSXTransform, since it's already included in nextJs.

configure({
  presets: [presets.react(), presets.nextJs()]
})
  • Enables new JSX transform support
  • Allows the usage of export default

remix preset doesn't provide React rules, so don't forget to add react preset too. You may omit newJSXTransform, since it's already included in remix.

configure({
  presets: [presets.react(), presets.remix()]
})

Libraries

  • Adds effector plugin and enables /recommended, /scope, and /react rules
configure({
  presets: [
    presets.effector({
      // (optional) Enables /future rules
      future: false
    })
  ]
})

Extends

[!IMPORTANT] The paths from "extend.ignorePatterns", "extend.overrides" and similar options defined in "extends" ESLint config are resolved relative to the current ESLint config

May be used in monorepos to declare shared ESLint Kit options for all packages.

Root .eslintrc.cjs example:

// <root>/base.eslintrc.cjs
const { configure, presets } = require('eslint-kit')

module.exports = configure({
  presets: [
    presets.imports(),
    presets.typescript(),
    presets.prettier(),
    presets.node(),
  ],
})

Package .eslintrc.cjs example:

// <root>/libs/my-library/.eslintrc.cjs
const { configure } = require('eslint-kit')

module.exports = configure({
  root: __dirname,
  extends: '../../base.eslintrc.cjs', // Resolved relative to "root"
})

Also accepts ESLint Config object, but only if it was created using ESLint Kit:

// <root>/libs/my-library/.eslintrc.cjs
const { configure } = require('eslint-kit')
const path = require('path')

module.exports = configure({
  extends: require(path.resolve(__dirname, '../../base.eslintrc.cjs')),
})

Internally, the local ESLint Kit options is just merged with the ESLint Kit options from "extends" config.

Some properties are deep merged, but some are simply overwritten.

The complete list of deep merged options:

  • presets
  • extend
  • extend.rules
  • extend.env
  • extend.globals
  • extend.plugins
  • extend.settings
  • extend.overrides

You may find the merging implementation in this source file.

Allow Debug

Useful in development mode.

Disables the following rules:

  • no-debugger
  • no-console
  • no-alert
  • effector/no-patronum-debug
const { configure, presets } = require('eslint-kit')

module.exports = configure({
  allowDebug: process.env.NODE_ENV !== "production",
  /* ... */
})

Linting Modes

const { configure, presets } = require('eslint-kit')

module.exports = configure({
  mode: 'decrease-level',
  /* ... */
})

Linting Modes are useful when you want to set similar behavior to a large number of rules.

default

Do not transform rule levels. This is the default value.

decrease-level

Transform error to warn, and warn to off.

It's useful for incremental adoption: you can focus on fixing only critical issues first.

only-errors

Transform warn to error.

It's useful when you want to completely prevent any warnings to get into your main branch.

only-warns

Transform error to warn.

I have no idea when this may be useful, but ok.

disable-warns

Transform warn to off.

I have no idea when this may be useful, but ok.

Common issues

Q: ESLint ignores my .eslintrc.cjs, why?
A: It's a regular issue with tools like @vue/cli and create-react-app. Check package.json and remove eslintConfig if you find it. Otherwise, try to restart your editor.

Q: ESLint: TypeError: this.libOptions.parse is not a function
A: Most likely you're using old broken ESLint version. 8.44.0 is tested and can be safely used.

Q: ESLint couldn't determine the plugin "foo" uniquely
A: Most likely your .eslintrc.cjs is located inside some nested project directory, and you have eslint package installed in the high-level node_modules. You can try setting extend.root to true like in the example below:

configure({
  presets: [/* ... */],
  extend: {
    root: true
  }
})

Q: In my monorepo, ESLint complains about tsconfig.json (or another file) location. How can I fix it?
A: Just set up root option inside your nested package (workspace) .eslintrc.cjs like in the example below:

configure({
  root: __dirname,
  presets: [/* ... */]
})

Q: I get another error when using eslint-kit in a monorepo A: We didn't test monorepos much. They often have different issues with eslint and plugins resolving. And we also don't guarantee that your aliases settings will work in monorepo.

Setting up editors

VSCode

Install ESLint VSCode extension:

Next, select from the following and click on it:

Click on Settings icon:

Select "Keyboard shortcuts"

Type "eslint" and click on "edit" button:

Finally, choose the keybind you like.

Click on Settings icon:

Select "Settings"

Switch to text mode:

Finally, add the following and save:

{
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
  ],
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  }
}

Contributing

  1. Fork this repo
  2. Switch to a new branch, it should start with feat/, fix/, docs/, refactor/, etc., depending on the changes you want to propose
  3. Make changes
  4. Create a Pull Request into this repo's main branch
  5. When the checks are done and the review is passed, I'll merge it into main and it will create a new record in the changelog. Then, when the release is finally ready, your changes will be released.

Maintenance

The dev branch is main - any developer changes is merged in there. Also, there is a release branch. It always contains the actual published release source code and tag.

All changes are made using Pull Requests - push is forbidden. PR can be merged only after successful test-and-build workflow checks.

When PR is merged, release-drafter workflow creates/updates a draft release. The changelog is built from the merged branch scope (feat, fix, etc) and PR title. When the release is ready - we publish the draft.

Then, the release workflow handles everything:

  1. We run tests and build a package
  2. Then, we merge release tag into the release branch
  3. After, we restore build artifacts and publish it to NPM

Also, this repo has Renovate bot set up to auto-update typescript preset dependencies (they change frequently). The bot creates a PR into main branch and automatically merges it after successful checks.