8 ESlint plugins for your NodeJs app

Using Eslint in your project is an easy way to improve productivity and reduce low-value, subjective code-style comments from pull requests. It will make your code consistent and easy for the next developer to read and we should always be optimising for readability.

Using some specific Eslint plugins will also prevent real bugs and security issues in TypeScript and JavaScript applications through static analysis.

Here I’ll explain why it’s so important to use ESLint in your application and I’ll describe the plugins I always add to every new NodeJs application to massively improve code quality and consistency.

Why I use ESLint on every project

I use ESLint on all my professional work to ensure consistency for the entire team and to make sure we’re writing a standard typescript/javascript in all files. Making it easier for other developers to understand our code quickly is one of the easiest ways to improve productivity in a development team.

I also use Eslint on all my personal projects because it’s like having an additional senior dev watching my back every time I commit code. I make mistakes all the time when working alone so I need all the help I can get! Eslint plugins contain the experience of all the developers who spent the time writing rules. It would be silly to not use this knowledge.

Here’s some details on the reasons you should use Eslint and all these awesome plugins.

Eliminating subjective arguments

Most ESLint rules are subjective code-style type rules. Once you lock in a setting for code-style then ESLint will enforce it. This is the key benefit for these types of stylistic rules. If you’re getting lots of “nit” type comments in PRs just add an eslint rule to make them stop by having Eslint fix them for you automatically before you show the PR to colleagues.

If someone disagrees with a configured Eslint rule that’s no problem - in fact these discussions should be welcomed because it shows the person cares about the code.

To resolve these rule change requests, just let the team vote and if the vote is successful the person that wants to change the rule can go ahead and change it BUT - they also have to make all the existing code compliant.

This usually isn’t a large task with eslint auto-fixes or just search and replace.

Having consistency across your code base is important for readability, quality and onboarding new developers. They specific code styles used doesn’t matter so much, most developers will just adjust in a few days or less as they jump across code bases.

But your rules should be internally consistent for the specific code base.

Preventing objective code smells

In addition to styles and code consistency some of these eslint plugins will objectively improve your product and prevent real bugs. They perform static analysis for specific libraries that even tooling like typescript won’t detect.

The sonar plugin in particular has some interesting code smell detections worth trying out.

These types of rules are often objectively beneficial and should be configured on EXCEPT where they are redundant because something like typescript already covers them, they are too restrictive, or they’re just not relevant to your code.

Learning and keeping up to date

When you activate all the plugins I list here you will have 100s of tests of your code on each linting run.

You effectively have expert JavaScript developers pair programming with you all day, suggesting the best way to write your software as you build it.

It’s just not realistic to expect a single engineer to remember to apply all these rules to each commit. For newer developers seeing these rules can be a great way to learn good practices by following the explanations in documentation.

And the best thing is that these plugins are under active development so they will be updated as the JavaScript industry learns and improves.

The value you get from adding these eslint plugins to your project is equivalent to adding an additional dev and an additional QA to your team.

8 must have ESlint plugins

Hers’s a list of the plugins I use on all my projects and I’ve added some additional notes about plugins I don’t find useful.

1. eslint-plugin-unicorn

Eslint unicorn is just brilliant! It’s a list of all kinds of rules to help with JavaScript projects.

Unicorn will remind you to use array.includes instead of some or find if you’re working on a list of strings for example. There are too many awesome rules to list each here so check out their docs.

This plugin is a must have!

Unicorn is updated regularity and is a nice way to get lazy updates on what’s happening in the JavaScript world. For example I recently learned about the node: scheme for being more explicit about importing Node.js libraries from unicorn.

import fs from 'fs'

// Vs

import fs from 'node:fs'

There are some rules in unicorn that I disable or change like abbreviations. For example you’ll use abbreviations like “res” or “req” all over your controllers if you use NestJs or express. You will want to tell unicorn to ignore those.

Here are some of my disabled unicorn rules.


  "unicorn/no-fn-reference-in-iterator": "off",
  "unicorn/no-array-for-each": "off",
  "unicorn/no-null": "off",
  "unicorn/consistent-destructuring": "off",
  "unicorn/no-array-reduce": "off",
  "unicorn/prefer-spread": "off",
  "unicorn/no-array-callback-reference": "off",
  "unicorn/consistent-function-scoping": "off",
  "unicorn/no-useless-undefined": "off",
  "unicorn/prevent-abbreviations": [
      "error",
      {
          allowList: { Param: true, Req: true, Res: true },
      },
  ],

Get it: https://github.com/sindresorhus/eslint-plugin-unicorn

2. eslint-plugin-import

This plugin will warn you if you do anything sketchy with module imports. If you use typescript make sure you add the recommended rules for typescript so you don’t get conflicts.

  extends: [
        "plugin:import/errors",
        "plugin:import/warnings",
        "plugin:import/typescript", // make sure you add this one for ts projects
    ],

Also remember to set the parser options for typescript

    settings: {
        ["import/parsers"]: { "@typescript-eslint/parser": [".ts", ".tsx"] },
        ["import/resolver"]: {
            node: {
                extensions: [".ts"],
            },
        },
    },

Typescript will already find any unresolved modules for you but this plugin is still useful for consistency like forbidding named default imports.

Get it: https://github.com/benmosher/eslint-plugin-import

3. @typescript-eslint/eslint-plugin

This plugin is a must have if you’re using typescript in your project. Just make sure you set up the typescript parser correctly by following the instructions on their readme.

This is the bit of config I use

{
  parser: "@typescript-eslint/parser",
  parserOptions: {
    project: "tsconfig.json",
    sourceType: "module",
    ecmaVersion: "es2019",
  },

There are 50 rules or more here so you’ll have to read the documentation yourself.

The default recommended rule set is excellent but if you’re adding this to an existing project you might have too many errors. Disable the worst rules for now and work at refactoring out the issues.

There is a naming-convention rule that you should configure for your project and your organisation. It’s worth getting familiar with this rule and setting it up instead of turning it off. Here is an example

  "@typescript-eslint/naming-convention": [
            "error",
            {
                selector: "default",
                format: ["camelCase"],
            },
            {
                selector: "variable",
                format: ["PascalCase", "UPPER_CASE"],
                types: ["boolean"],
                prefix: ["is", "should", "has", "can", "did", "will"],
            },
            {
                selector: "variableLike",
                format: ["camelCase", "UPPER_CASE", "PascalCase"],
            },

            {
                selector: "parameter",
                format: ["camelCase"],
            },
            {
                selector: "memberLike",
                modifiers: ["private"],
                format: ["camelCase"],
                leadingUnderscore: "forbid",
            },
            {
                selector: "typeLike",
                format: ["PascalCase"],
            },
            {
                selector: "property",
                modifiers: ["readonly"],
                format: ["PascalCase"],
            },
            {
                selector: "enumMember",
                format: ["UPPER_CASE"],
            },
        ],

Get it: https://github.com/typescript-eslint/typescript-eslint#readme

4. eslint-plugin-eslint-comments

This is a meta eslint plugin but very useful. It analysis the comments you can use to control how Eslint parser your code. This will help you have great comments that describe eslint directives like

/*eslint-disable no-undef */

In particular it will spot useless ignores that you leave behind from after you refactor something or when you forget to re-enable a rule. This is well worth adding to your project.

You might want to change the rule for eslint pairs so that it allows using Eslint disable comments for entire files. I find preventing complete file rule disabling is too restrictive.

 "eslint-comments/disable-enable-pair": [
     "error",
     { allowWholeFile: true },
 ],

Get it: https://github.com/mysticatea/eslint-plugin-eslint-comments#readme

5. eslint-plugin-sonarjs

This plugin detects code smells like duplicate functions, duplicate string usage or switch statements with too many conditions.

One very interesting rule in SonarJS will try to prevent codeblocks that present too much cognitive complexity. This is a special Sonar specific measure that builds on cyclomatic complexity. There is more detail here: https://www.sonarsource.com/docs/CognitiveComplexity.pdf

There are too many rules to go through in this rule set but sonar’s js plugin is really useful and you should check it out.

Get it: https://github.com/SonarSource/eslint-plugin-sonarjs

6. eslint-plugin-jest

The jest Eslint plugin is a really worthwhile addition to your code. I make so many mistakes in jest tests without it.

For example, did you know that you should always return asynchronous expects?

expect(myResult).resolves.toEqual(expected) // this is wrong
return expect(myResult).resolves.toEqual(expected) // this is correct

If you don’t return you can get a hanging promise and an Jest test run that slows everything down.

Sometimes I accidentally do my assertion in the expects like this

expect(myResult === expected)

This doesn’t error but it doesn’t assert your test case as expected at all. You’ll get passes!

The jest eslint plugin will prevent these very dangerous errors and much more.

https://github.com/jest-community/eslint-plugin-jest

7. eslint-plugin-nestjs-typed

Shameless plug here because I wrote this plugin. I use NestJs for all my backend web projects so I always add this plugin to my projects.

eslint-plugin-nestjs-typed does two things.

It will remind you of any injectable services that you’re not providing in a module. It will do this statically instead of waiting for the nest js runtime.

If you use swagger it will prompt you to apply the correct decorators for most scenarios to ensure any code gen you run on the swagger will product correct models.

Check it out if you use nestjs!

https://github.com/darraghoriordan/eslint-plugin-nestjs-typed

8. eslint-plugin-promise

This plugin is useful for at least one rule. It forces you to always return a value from a promise or a then().

There is another rule here that enforces either async/await or then()/catch(). This could be useful at the start of a project to force one or the other.

Typescript and unicorn cover most of the other rules here so you might not need this one. I still recommend it.

Get it: https://github.com/xjamundx/eslint-plugin-promise

Bonus: Interesting ESlint plugins for specific projects

eslint-plugin-lodash

Rules for lodash if you have lodash in your project. I use lodash very minimally these days so I don’t use this plugin. If I do start to use lodash more often I would use the plugin again for sure.

Get it: https://github.com/wix/eslint-plugin-lodash

eslint-plugin-no-secrets

This plugin detects strings that look like they could be secrets. This is a really clever plugin but I found that it was extremely sensitive and difficult to configure correctly. You might have a better experience with this though.

It’s worth trying if it’s that secrets are never in your app.

Get it: https://github.com/nickdeis/eslint-plugin-no-secrets#readme

eslint-plugin-html

This plugin can lint JavaScript inlined into your html. I would only add this if I had lots of inline JavaScript in html files. This is unlikely in modern js applications but there is quite a bit of legacy JavaScript out there.

Get it: https://github.com/BenoitZugmeyer/eslint-plugin-html

eslint-plugin-markdown

This plugin will parse code in your markdown files. This is useful if you were creating professional technical documentation or similar.

I have code snippets all over this blog but I still don’t use this plugin anymore because vscode formats my code in markdown now.

Get it: https://github.com/eslint/eslint-plugin-markdown

ESlint Plugins to avoid

eslint-plugin-node

I haven’t found massive value in these rules but I mostly use Node.js for web application development.

Get it: https://github.com/mysticatea/eslint-plugin-node

eslint-plugin-json

I don’t use this plugin because vscode’s JSON language features cover most of the rules already. I recommend using your IDE instead of this.

If most of your developers will be using an IDE of some kind you might be able to skip this plugin. If your devs are using text editors to write json then add this to your CI.

Get it: https://www.npmjs.com/package/eslint-plugin-json

Darragh ORiordan

Hi! I'm Darragh ORiordan.

I live and work in Sydney, Australia building and supporting happy teams that create high quality software for the web.

I also make tools for busy developers! Do you have a new M1 Mac to setup? Have you ever spent a week getting your dev environment just right?

My Universal DevShell tooling will save you 30+ hours of configuring your Windows or Mac dev environment with all the best, modern shell and dev tools.

Get DevShell here: ✨ https://usemiller.dev/dev-shell


Read more articles like this one...

List of article summaries

#nodejs

Running a NodeJS app with Postgres in Dokku

I have some side projects that don’t see much traffic so I run them on a 5$ Digital Ocean droplet running Dokku.

Dokku is an open source Heroku-like platform. It’s super easy to create and maintain multiple applications on a Dokku instance. It’s perfect for solo makers.

There are plugins for most of the common services you might want like PostgreSQL or Redis.

Here’s what we’re going to do

  1. A Brief overview of Dokku
  2. How to get a Dokku instance running
  3. Create a new Dokku application
  4. Add a database service
  5. Expose the database for debugging and testing (Optional)
  6. Add a domain to the application
  7. Add any configuration variables for your application
  8. Add SSL to the application
  9. Add the Dokku remote to your application
  10. Push your application to Dokku
  11. Maintaining your Dokku server
#nodejs

npmrc authentication for a private scoped organisation package

When you have to login to npm for multiple organisations it can be easier to use an .npmrc file that you move around rather than npm login command.

#nodejs

Semantic versioning javascript projects but skipping NPM publish

If you want to use semantic versioning and automate release versions using semantic-release for your front-end client application you probably don’t want to actually publish it to npm.

Here is how to use semantic-release while not releasing to npm.

#nodejs

Avoid these issues when using new ECMAScript modules in your Node.js application

ECMAScript modules are the official standard format to package JavaScript code for reuse in the future. Es6 modules now have full support in Node.js 12 and above so it’s time to start using them.

JavaScript developers and node libraries have typically used commonjs for modules up to now. If you’ve used typescript in the past few years you will be familiar with the module import syntax in you application. Instead of commonjs require("module") most typescript applications use some variation of import module from "module".

Typescript will then transpile this import syntax into commonjs require statements for you. This step is not necessary in modern Node.js applications. You can just use import module from "module" directly in your transpiled code.

If you use typescript you can change just change your tsconfig settings to output ECMAScript es6 modules and you will be good to go. If you don’t use typescript you might have to do some rewriting if you want to get your app updated.

Here are solutions to the issues that took me a bit of time and investigation to figure out when I was upgrading my Node.js application to use ECMAScript modules like configuring typescript, setting up jest, configuring the package.json correctly and more.

Comments