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-config-peerigon

v40.0.0

Published

Peerigon coding rules as eslint config

Downloads

2,411

Readme

eslint-config-peerigon

Peerigon coding rules as ESLint config.

Version on NPM Semantically released Monthly downloads on NPM License

Linting and formatting rules are always a balance between

  • ease of reading
  • ease of refactoring
  • ease of writing.

We think that

  • code is read more often than refactored
  • and refactored more often than written from scratch.

Our linting rules have been designed with these assumptions in mind.

Table of contents

Quick start

Recommended configuration in your package.json:

{
    "scripts": {
        "test:lint": "eslint --max-warnings 0 --cache --ext js,jsx,cjs,mjs,ts,tsx --ignore-path .gitignore .",
        "posttest": "npm run test:lint"
    }
}

We also offer a Prettier config that matches our ESLint config. Create a .prettierrc.json in your project with the following content:

"eslint-config-peerigon/prettier.config.js"

There are presets for the most common setups:

TypeScript

npm i eslint eslint-config-peerigon --save-dev
{
    "extends": [
        "peerigon/presets/typescript.js"
    ],
    "env": {
        "node": true
    },
    "root": true
}

TypeScript + React

npm i eslint eslint-config-peerigon eslint-plugin-react eslint-plugin-jsx-a11y eslint-plugin-react-hooks --save-dev
{
    "extends": [
        "peerigon/presets/typescript-react.js"
    ],
    "env": {
        "node": true,
        "browser": true
    },
    "root": true
}

TypeScript + Node

npm i eslint eslint-config-peerigon eslint-plugin-n --save-dev
{
    "extends": [
        "peerigon/presets/typescript-node.js"
    ],
    "root": true
}

Practical guide

Disabling rules

Try to disable as less rules as possible. In most cases it's best to just write

// eslint-disable-next-line [rule-code]

where [rule-code] is the code that is displayed along the error message. Disabling the next line is usually better because it resists Prettier reformatting.

Sometimes it makes sense to disable a rule within a specifc file. In that case you can put the following snippet at the beginning of the file:

/* eslint-disable [rule-code] */

If you don't agree with a rule, please do not just disable the rule. Often there are good reasons and the current setting is the result of years of experience. It's better to create an issue here to start a discussion about the pros and cons of a rule.

Different styles

We acknowledge that there are certain rules where there are no actual pros and cons or where there is no clear winner. You just have to decide for one style and stick with it. We also know that some rules make sense in one project, but don't make sense in another project. That's why we also provide a list of accepted custom styles (see also this discussion) which you can pick.

VSCode

This is our recommended VSCode configuration using the Prettier extension. Adjust it to the needs of your particular project:

{
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true
    }
}

Experimental syntax using Babel

If you're using Babel you should set requireConfigFile: true in your ESLint config. ESLint will then use your babel.config.json.

{
    "parserOptions": { "requireConfigFile": true },
}

Naming conventions for properties

Sometimes we're not in full control over the naming conventions in our codebase, for instance if data is coming from a foreign API. While it often is preferable to transform property names into camelCase, it might not be practical. In these situations you can disable the check for properties like this:

const options = require("eslint-config-peerigon/options.js");

module.exports = {
    /* ... */
    rules: {
        // The API uses snake_case as properties
        camelcase: [
            "warn",
            {
                ...options["camelcase"],
                properties: "never",
            },
        ],
    },
};

In TypeScript projects:

const options = require("eslint-config-peerigon/options.js");

module.exports = {
    /* ... */
    rules: {
        // The API uses snake_case as properties
        "@typescript-eslint/naming-convention": [
            "warn",
            options["@typescript-eslint/naming-convention"].ignoreProperties,
            ...options["@typescript-eslint/naming-convention"].defaultRules,
        ],
    },
};

Provided configs

peerigon

Base rules for every project. You should always add these rules.

npm i eslint eslint-config-peerigon --save-dev

These rules assume a modern project with full ES2015 support, including ES modules. For specific environments like Node.js or old JS engines, see below. The base rules do not define an env, so you might want to do that for yourself to enable specific globals.

Add an .eslintrc.json to the project's root folder:

{
    "extends": [
        // Base rules for every project
        "peerigon"
    ],
    // Do not search for further eslint configs in upper directories
    "root": true,
    // If you're using Babel, you should set requireConfigFile: true
    // ESLint will then use your babel.config.json.
    // "parserOptions": { "requireConfigFile": true },
}

The base rules use the eslint-plugin-import to resolve imports. Although it's possible to define custom resolvers, it's highly discouraged to deviate from the common Node.js resolving algorithm. Other tools like linters and intellisense don't work reliably when you change the resolver.

peerigon/typescript

Rules for TypeScript.

{
    "extends": [
        "peerigon",
        "peerigon/typescript",
        // Arrow functions are preferred with TypeScript
        // See https://github.com/peerigon/eslint-config-peerigon/issues/23#issuecomment-472614432
        "peerigon/styles/prefer-arrow"
    ],
    "root": true,
}

You need to add --ext js,jsx,cjs,mjs,ts,tsx to the test:lint script:

{
    "scripts": {
        "test:lint": "eslint --max-warnings 0 --cache --ext js,jsx,cjs,mjs,ts,tsx --ignore-path .gitignore ."
    }
}

We recommend using peerigon/styles/prefer-arrow because arrow functions (or function expressions in general) can leverage TypeScript's contextual typing.

peerigon/node

Important: Requires eslint-plugin-n.

npm i eslint-plugin-n --save-dev
{
    "extends": [
        "peerigon",
        "peerigon/node"
    ],
    // Setting env.node = true is not necessary, this is already done by peerigon/node
    "root": true
}

peerigon/react

Important: Requires eslint-plugin-react, eslint-plugin-jsx-a11y and eslint-plugin-react-hooks as project dependency.

npm i eslint-plugin-react eslint-plugin-jsx-a11y eslint-plugin-react-hooks --save-dev

Rules for React development, including accessibility rules. These rules are also applicable in other JSX environments, like Preact:

{
    "extends": [
        "peerigon",
        "peerigon/react"
    ],
    "root": true
}

We recommend using peerigon/styles/react-jsx-no-literals if you're using i18n in your project. You can use peerigon/styles/react-jsx-no-bind if you're using memo and shouldComponentUpdate a lot.

peerigon/jsdoc

Important: Requires eslint-plugin-jsdoc as project dependency.

npm i eslint-plugin-jsdoc --save-dev

Makes sure that JSDoc annotations are written in a standard-compliant and uniform way.

{
    "extends": [
        "peerigon",
        "peerigon/jsdoc"
    ],
    "root": true
}

Styles

The following rules enable specific writing styles. Use them as you prefer.

peerigon/styles/prefer-arrow

Enforces arrow function expressions instead of function declarations (see #23). Regular functions are still allowed as methods in objects or classes.

    "extends": [
        "peerigon",
        "peerigon/styles/prefer-arrow"
    ],

peerigon/styles/no-default-export

Forbids usage of export default. When using default exports, it becomes harder to name classes or functions consistently throughout the codebase since every module can pick its own name for the imported thing. Nicholas C. Zakas, the creator of ESLint, wrote an article with more compelling arguments why he stopped using export default.

    "extends": [
        "peerigon",
        "peerigon/styles/no-default-export"
    ],

Please note: This rule is disabled in .jsx and .tsx files because React components are usually exported via export default. React.lazy even expects the lazy loaded component to be exported as default.

peerigon/styles/no-null

Important: Requires eslint-plugin-no-null as project dependency.

npm i eslint-plugin-no-null --save-dev

Forbids the usage of null. In a codebase it's often better to use a single non-value to represent the absence of a value. With the rise of default parameters and destructuring defaults, JavaScript developed a clear tendency towards undefined. This issue summarizes the arguments (and trade-offs) of null vs. undefined.

    "extends": [
        "peerigon",
        "peerigon/styles/no-null"
    ],

Please note: If you use this rule, you will probably still need a single null value which you can refer to whenever you need to use null because of third-party code:

// eslint-disable-next-line no-null/no-null
export const NULL = null;

peerigon/styles/prefer-interface

Important: Use it in combination with peerigon/typescript.

Prefer interface over type.

    "extends": [
        "peerigon",
        "peerigon/typescript",
        "peerigon/styles/prefer-interface"
    ],

peerigon/styles/react-jsx-no-bind

Important: Use it in combination with peerigon/react.

Depending on the way you write your components, it might be not ok to create functions during render(). Use it if you're using things like React.memo() or shouldComponentUpdate a lot.

    "extends": [
        "peerigon",
        "peerigon/react",
        "peerigon/styles/react-jsx-no-bind"
    ],

peerigon/styles/react-jsx-no-literals

Important: Use it in combination with peerigon/react.

Use this style if you're using i18n. It prevents people from putting raw strings in components.

    "extends": [
        "peerigon",
        "peerigon/react",
        "peerigon/styles/react-jsx-no-literals"
    ],

It disallows this:

const Hello = <div>test</div>;

As an escape hatch, this is still allowed:

const Hello = <div>{"test"}</div>;

peerigon/styles/prefer-array-shorthand

Important: Use it in combination with peerigon/typescript.

Enforces typescript arrays to use the shorthand array-style instead of the generic style.

    "extends": [
        "peerigon",
        "peerigon/typescript",
        "peerigon/styles/prefer-array-shorthand"
    ],

It enforces this:

const foo: string[] = [];

instead of

const foo: Array<string> = [];

License

Unlicense

Sponsors