Package Exports
- eslint-config-sheriff
- eslint-config-sheriff/package.json
Readme
Sheriff
Note For a better reading experience, checkout the official docs.
π Table of Contents
- π Table of Contents
- π Description
- β¨ Features
- π οΈ Setup
- π₯οΈ Techs
- π Requirements
- π Eslint plugins
- π§Ά Rules
- π§ Configuration
- π Prettier support
- π VSCode support
- π Monorepo support
- π§ Prior art
- β» Migration guide
- π§‘ Contributing
- π€ Changelog
- π License
- π Faq
- π Acknowledgments
π Description
π₯³ Introduction
Sheriff is a comprehensive Eslint configuration. It supports various popular technologies.
β οΈ At the moment, Sheriff supports only Typescript codebases with modern Ecmascript standards. Support for vanilla Javascript will come at a later time.
π Key points
- This library is pioneering in the adoption of the Eslint
FlatConfig
, introduced in Eslint v8.23.0. - Sheriff is very easy to get started with and use. It promotes a βzero overhead approachβ. See: philosophy.
- Itβs a "plug & play" solution but you can customize it as much as you want. See: features.
π€ Why / Motivations
Managing a complex Eslint configuration takes time and effort. Sheriff does it for you.
π Philosophy / Criteria
This library is very opinionated, but it's for the better. I took a lot of decisions so you don't have to [^2].
You can now quickstart static analysis in all your Typescript projects with ease. Just type create-sheriff-config
in a CLI and you are good to go.
You can think of Sheriff like prettier
or create-react-app
. It's a tool that comes battery-packed with optimal defaults. It removes configuration decisions from the equation, so you or your team can focus on developing the actual product.
And if you don't like something, you can easily override it, and just as easily you can extend it. See: configuration.
[^2]: This config is particularly useful for big teams with developers of various skill levels. Sheriff was made to prevent all kind of mistakes and to align the team on the same playing field. It is battle-tested in real-world scenarios and shines especially in such.
β¨ Features
- β‘ Batteries included: Sheriff is a all-in-one solution. You don't need to install or configure separately anything else. Everything is included here.
- π No lock-in: Sheriff is not a framework. You can extend the
eslint.config.js
beyond Sheriff as much as you like, just like you normally would. Or you can disable any rule Sheriff comes with. Sheriff doesn't impose any limitation. See: configuration. - π Frictionless by design: to setup Sheriff and take off, the only input required from the user is running the command
npx create-sheriff-config
. The command will automatically infer the details of your project and figure out the optimal Sheriff configuration by itself. - β Interoperability: you can plop Sheriff in your project at any moment.
create-sheriff-config
will config automatically everything for you and will warn you if you need to take any special precautions. Bottom line: it's never too late to install Sheriff. - π Cutting-edge: Sheriff is one of the first attempts in the wild to adhere to the new eslint configuration format, the
FlatConfig
. You can use Sheriff to easily and safely migrate your project to the new config format without effort. See: migration guide. - π Sensible: Almost all of the rules that were hand-picked in Sheriff were chosen to counter some problematic real-world scenarios that can occur in production projects and to ensure maximum style consistency. No bloat here.
- ποΈ Configurable: Sheriff is fully configurable with its own config object. See: configuration.
- π Modular: Sheriff has opt-in support for a wide array of libraries.
- β SemVer: Sheriff releases follows Semantic Versioning with Conventional Commits standards.
π οΈ Setup
This config is highly opinionated, so make sure to meet the hard requirements in your project.
Then, let create-sheriff-config
handle the whole setup for you automatically, or do it yourself manually.
For greenfield projects, the below setup will be enough. However, for already established codebases, you should also follow the instructions for the migration path.
π€ Automatic setup (recommended)
Let the CLI take care of everything!
Just run this command in your terminal:
β― npx create-sheriff-config
or
β― pnpx create-sheriff-config
Setup VSCode support (optional)
...and you are good to go! Happy hacking π
π« Manual setup
Follow these steps:
Install the package from npm.
# npm β― npm install -D eslint-config-sheriff # yarn β― yarn add -D eslint-config-sheriff # pnpm β― pnpm add -D eslint-config-sheriff
Create a
eslint.config.js
[^1] file at the root of your project and copy/paste the contents of the following snippet of code:// eslint.config.js import sheriff from 'eslint-config-sheriff'; import { defineFlatConfig } from 'eslint-define-config'; const sheriffOptions = { react: false, next: false, lodash: false, playwright: false, jest: false, vitest: false, }; export default defineFlatConfig([...sheriff(sheriffOptions)]);
or, if you already have a
eslint.config.js
in your project, add the Sheriff support, like this:// eslint.config.js import sheriff from 'eslint-config-sheriff'; // add this import { defineFlatConfig } from 'eslint-define-config'; // add this // my other imports... // add this const sheriffOptions = { react: false, next: false, lodash: false, playwright: false, jest: false, vitest: false, }; export default [ ...sheriff(sheriffOptions), // add this // my other configurations... ];
Configure Sheriff (optional)
Setup prettier (optional)
Setup VSCode support (optional)
[^1]: Sheriff is based on the new format of Eslint configs. You cannot extend Sheriff from a old config format, it wouldn't work.
π₯οΈ Techs
- Eslint
- Prettier
- Typescript (out of the box support)
- Storybook (out of the box support)
- React (opt-in)
- Next (opt-in)
- Lodash (opt-in)
- Playwright (opt-in)
- Jest (opt-in)
- Vitest (opt-in)
π Requirements
Hard requirements
Recommendations
π Eslint plugins
- @typescript/eslint
- eslint-plugin-etc
- eslint-config-prettier
- eslint-plugin-react
- eslint-plugin-jsx-a11y
- eslint-plugin-react-hooks
- eslint-plugin-react-refresh
- eslint-plugin-unicorn
- eslint-plugin-sonarjs
- eslint-plugin-fp
- @regru/eslint-plugin-prefer-early-return
- eslint-plugin-jsdoc
- eslint-plugin-tsdoc
- eslint-plugin-jest
- eslint-plugin-import with eslint-import-resolver-typescript
- eslint-plugin-lodash-f
- my fork of eslint-plugin-lodash
- @next/eslint-plugin-next
- eslint-plugin-playwright
- eslint-plugin-storybook
π§Ά Rules
See Rules.
π§ Configuration
The
eslint-config-sheriff
package exports asheriff
function.
You can configure Sheriff as desired using a simple javascript object as the first input parameter of thesheriff
function.
Every config option can be set on/off (you just pass them a boolean value). As they are all opt-in, they are all disabled by default.// eslint.config.js import sheriff from 'eslint-config-sheriff'; import { defineFlatConfig } from 'eslint-define-config'; // π Sheriff configuration object const sheriffOptions = { react: false, next: false, lodash: false, playwright: false, jest: false, vitest: false, }; export default defineFlatConfig([...sheriff(sheriffOptions)]);
You can override any Sheriff rule as desired in the
eslint.config.js
file.
For example, let's say you want to disable a Sheriff rule, likeimport/first
:// eslint.config.js import sheriff from 'eslint-config-sheriff'; import { defineFlatConfig } from 'eslint-define-config'; const sheriffOptions = { react: false, next: false, lodash: false, playwright: false, jest: false, vitest: false, }; export default defineFlatConfig([ ...sheriff(sheriffOptions), { rules: { 'import/first': 0, // π 'import/first' is now disabled everywhere. }, }, ]);
Likewise, let's say you want to enable a new rule:
// eslint.config.js import sheriff from 'eslint-config-sheriff'; import { defineFlatConfig } from 'eslint-define-config'; const sheriffOptions = { react: false, next: false, lodash: false, playwright: false, jest: false, vitest: false, }; export default defineFlatConfig([ ...sheriff(sheriffOptions), { rules: { 'import/first': 2, // π 'import/first' is now enabled everywhere. }, }, ]);
This is just the standard behavior of the new configuration system of Eslint, which I'm illustrating here for your convenience. Sheriff doesn't alter this in any way.
For more in-depth information, refer to the official docs.
Extra configuration options
These are kind of hidden configuration options. They are useful only for a niche handful of users, made to cover specific usecases. Use these only if you need them.
"files" option
Covered here: β» Migration guide
"customTSConfigPath" option
If you have multiple tsconfig.json
files in your project (like tsconfig.json
, tsconfig.eslint.json
, tsconfig.node.json
, etc...) you can specify which config Sheriff will pickup with the customTSConfigPath
option.
You can pass the path to it as a string in the sheriffOptions
object. Example:
// eslint.config.js
import sheriff from 'eslint-config-sheriff';
import { defineFlatConfig } from 'eslint-define-config';
const sheriffOptions = {
customTSConfigPath: './tsconfig.eslint.json',
react: false,
next: false,
lodash: false,
playwright: false,
jest: false,
vitest: false,
};
export default defineFlatConfig([...sheriff(sheriffOptions)]);
π Prettier support
Sheriff tries to incorporate prettier out-of-the-box.
The create-sheriff-config
command will spin up for you a default .prettierrc.json
configuration. You can modify it if you need to, but it is discouraged. Act with caution.
If you don't use the create-sheriff-config
command, you will have to provide a prettier config yourself. Also don't forget the .prettierignore file.
If you already have a prettier config in your project, the create-sheriff-config
command won't create a new prettier config, nor will attempt to modify the existing one.
Sheriff comes with the rules of eslint-config-prettier out-of-the-box.
By design, Sheriff doesn't incorporate eslint-plugin-prettier. Its use is discouraged by the prettier team itself, as it just slows down your editor.
Instead, for your local editing experience, it's recommended to install a editor extension.
If you want to enforce Prettier at pre-commit stage, see the official docs.
To enforce Prettier in CI, see the CLI docs.
π VSCode support
The Eslint FlatConfig
support is currently not enabled by default by the VSCode Eslint extension. It needs to be enabled manually with a flag.
It's advisable to enable it at the workspace level, meaning in the project .vscode/settings.json
, like so:
// settings.json
{
"eslint.experimental.useFlatConfig": true
}
π Monorepo support
While Sheriff can be made to work at the root of monorepos, it is highly advisible to not do so.
It works fine in singular packages inside monorepos.
Monorepo support in VSCode
To make use of the Eslint VScode extension in monorepos, use the eslint.workingDirectories setting.
π§ Prior art
Related projects
- eslint-config-galex
- eslint-kit
- eslint-config-everywhere
- xo
- eslint-plugin-canonical
- eslint-prettier-typescript-config
- eslint-config-airbnb-typescript
Comparisons
The main difference between Sheriff and the other projects is that Sheriff is updated to the most recent version of Eslint and supports the new FlatConfig
instead of relying on weird hacks using the @rushstack/eslint-patch.
There are of course other differences as well, but you can get an idea for yourself by reading their READMEs.
β» Migration guide
If you are setting up Sheriff in an already established codebase, follow these steps:
Start by running the
create-sheriff-config
command and follow the advices that it prints in the console.Make sure that the only eslint config file present in the whole project is the
eslint.config.js
.If you want to keep your existing custom rules on-top of Sheriff, move them to the
eslint.config.js
, after thesheriff
config. Refer to the configuration instructions.Make sure to uninstall all the packages that Sheriff already incorporates out-of-the-box. Here is the list.
In massive codebases it can be troublesome to adapt to all these rules all at once. It is preferable to progressively fix the errors at your own pace, possibly with atomic commits. You can achieve this by leveraging 2 techniques:
open the
eslint.config.js
file and add a keyfiles
in thesheriffOptions
object. The value accepts an array of filepaths, dictated by minimatch syntax. Only the matching files found in this array will be linted. See example below:// eslint.config.js import sheriff from 'eslint-config-sheriff'; import { defineFlatConfig } from 'eslint-define-config'; const sheriffOptions = { files: ['./src/**/*'], // π Only the files in the src directory will be linted. react: false, next: false, lodash: false, playwright: false, jest: false, vitest: false, }; export default defineFlatConfig([...sheriff(sheriffOptions)]);
Note By default, the
files
key is absent in the object and every js/ts file will be linted. Use this only if you want to specifically lint just a subsection of the codebase.use eslint-interactive.
π§‘ Contributing
Suggestions
Feel free to propose suggestions about new rules to implement, or tweaks to existing rules.
Please use the discussions tab or the issues tab for new rules proposals.
Development
- Clone the repo
- Install the dependencies with pnpm
- Do the changes
π License
π€ Changelog
See Releases.
π FAQ
- Why you didnβt include Eslint plugins/rules for "X" library?
- Cypress β Don't use Cypress. Use Playwright instead.
- Testing library β I believe testing library is one of the least efficient ways to test UIs. In most codebases it does more harm than good. You can use Storybook to test and develop components in isolation.
- Is Sheriff compatible with "X"?
- Vite β Yes.
- Next.js β Yes. Sheriff has explicit support for Next.js. You can enable it in the Sheriff config options.
- CRA β Yes. Just add this line to your
.env
file:DISABLE_ESLINT_PLUGIN=true
- Rome β No. Rome is not compatible with Eslint in the first place.
- Deno β No. Deno is not compatible with Eslint in the first place.
- Bun β Untested.
π Acknowledgments
For some of this config i partially used eslint-config-red as a base.
Also took inspiration from eslint-config-airbnb for some of the rules in no-restricted-syntax
.
I don't take any attribution for the rules in the various eslint-plugins used here (except for the few that I personally created). Please consider starring the respective projects for the awesome work their authors made. Sheriff wouldn't be possible without their efforts.
The full list of the plugins used is here.