Modern, faster alternatives to ESLint
Tags: eslint
Published: 2022-05-03 13:12:07

**Written by [Godson Obielum](https://blog.logrocket.com/author/godsonobielum/)✏️**

In this article, we will look at specific open source libraries that either serve as alternatives to ESLint or can be integrated with ESLint. Some of these libraries are built to outright replace ESLint and improve on aspects such as performance or developer experience. In contrast, other libraries are not meant to replace [ESLint](https://blog.logrocket.com/linting-typescript-using-eslint-and-prettier/) but are supplemental, i.e., they leverage its features by integrating with it, thereby providing a more robust set of features. We'll focus on libraries that work well within the JavaScript ecosystem.

Before we get into the meat of the article, let's briefly look at what linters and code formatters provide and why we may want to use them when working on a project.

### Contents

*   [Advantages of linters and code formatters](#advantages-of-linters-and-code-formatters)
*   [What is ESLint?](#what-is-eslint)
*   [Modern alternatives to ESLint](#modern-alternatives-to-eslint)
    *   [Rome](#rome)
    *   [quick-lint-js](#quick-lint-js)
    *   [Standard JS](#standard-js)
    *   [Putout](#putout)
    *   [JSHint](#jshint)
*   [Libraries to integrate with ESLint](#libraries-to-integrate-with-eslint)
    *   [Prettier](#prettier)
    *   [Babel](#babel)
    *   [webpack](#webpack)

    ## Advantages of linters and code formatters

    The core purpose of a linter is to help you improve your code. This improvement is made possible by analyzing your code and informing you of emerging problems based on custom or default rulesets that have been preconfigured. These rulesets are called `rules` in ESLint. In essence, through these rulesets, linters help development teams achieve a consistent coding style and find bugs that may occur due to inconsistent coding styles. On the other hand, a code formatter enforces a consistent style by parsing your code and reprinting it with its own rules. It takes your code editor's maximum line length setting into account and wraps code when necessary. An example of a famous code formatter is [Prettier](https://blog.logrocket.com/using-prettier-eslint-automate-formatting-fixing-javascript/); we'll go in-depth into it in the coming sections.

    ## What is ESLint?

    ESLint falls under the category of a linter that we went through in the previous section. It is one of the most popular JavaScript linting tools available and currently has around 24 million weekly downloads. It primarily excels at doing two things: it finds problems with your code, and fixes them automatically. ESLint is either built in to most text editors or available to be integrated as extensions, indicative of its widespread popularity. It is highly customizable, and you can extend upon the default rules to write custom rules based on your project's needs. ESLint's parser is syntax-aware (it can understand the relationship between your code syntax) so your chances of encountering inconsistent errors produced by traditional find-and-replace algorithms are pretty low. Next, let's look at two classes of libraries: those that can serve as alternatives to ESLint and those we can integrate with ESLint.

    ## Modern alternatives to ESLint

    ### Rome

    [Rome](https://rome.tools/) is a toolchain that aims to unify functionality (such as formatting, linting, bundling, etc.) provided by multiple libraries. It is designed to replace ESLint and other tooling libraries in the JavaScript ecosystem, such as Babel, webpack, Prettier, and others. Rome aims at building upon a joint base to deliver a solid experience for processing code, displaying errors, and configuration. Rome has strict conventions that it enforces, allowing only minimal configuration. Rome also has first-class IDE support, with a sophisticated parser representing the source text in full fidelity, and top-notch error recovery.

    #### Advantages of Rome over ESLint

    ##### Performance

    Initially, Rome was built in JavaScript but is now being re-written in Rust; the intention is that such a fundamental shift in the architecture will bring massive improvements in performance, memory usage, and type safety without compromising on other areas such as flexibility.

    ##### Third-party dependencies

    Through Rust, the developers can create internal APIs that focus on essential needs such as correctness rather than depending on third-party JavaScript dependencies_._ This is a result of the emphasis by Rust and its community which allows Rome to use dependencies from the community without making tradeoffs around code size and performance.

    ##### Features

    Rome is much more than a linter, it is a combination of several tools under one library, and therefore, Rome provides way more functionalities and features than ESLint. Rome is still in development, although the parsing and code formatting features have been released and are available through [npm](https://www.npmjs.com/package/rome). In summary, its aims are lofty, and with time it could be a significant disruptor to tooling in the JavaScript ecosystem.

    ### quick-lint-js

    Quick-lint-js is a JavaScript linting tool; it helps us find bugs in our JavaScript program and gives us instant feedback on our code, highlighting syntax errors where necessary. It is minimalistic and allows us to use the tool without custom configurations or extra plugins. Quick-lint-js is designed to be an alternative to ESLint, and there are certain aspects in which it excels over ESLint, so let's take a look at some.

    #### Advantages of quick-lint-js over ESLint

    ##### Performance

    According to these [benchmarks](https://quick-lint-js.com/benchmarks/), against certain constraints such as input latency, quick-lint-js is over 130 times faster than ESLint. The benchmarks also help its claim as the quickest JavaScript linter and the least energy consumer.

    ##### Small design, fewer features

    Quick-lint-js’ minimalistic design contributes to its performance as less infrastructure and fewer components reduce runtime parsing costs, meaning quick-lint-js can sooner give feedback on syntax errors.

    ##### No configuration

    It works out of the box and doesn't require any custom configuration files to get it working. Quick-lint-js is a worthy choice to consider, especially if you're looking at high performance, ease of use, and less bloat due to size. However, ESLint still reigns as king in community support, the number of rules supported, and custom configuration/customizability.

    ### Standard JS

    [**Standard JS**](https://standardjs.com/) is a JavaScript linter, code styler, and formatter. It enforces a zero-configuration approach rather than the custom configuration used in ESLint through an `.eslintrc.json` file. This is exemplified by the fact that users must prioritize community conventions over personal style.

    #### Advantages of Standard JS

    ##### Simplicity

    Standard JS provides a straightforward way to enforce code quality in a project by completely removing the possibility of custom configuration. There is no `.eslintrc.json` kind of configuration file to manage; Standard JS manages everything for us.

    ##### Automatically formats code

    Standard JS provides a simple command to fix inconsistent code by running `standard --fix`. Standard JS is worth considering if you're okay with using conventions and style guides created by the community. However, if you need the flexibility of custom configuration based on team/personal preferences, ESLint is better.

    ### Putout

    [Putout](https://discourse.world/h/2020/05/30/Putout:new-generation-linter) is a code transformer based on Babel and has inbuilt support for ESLint. It is highly configurable and leverages a plugin system, meaning all rules are available as plugins. This keeps the initial API minimal and allows developers to extend upon it by installing only the rules they need. Putout consists of three core modules: Parser (parses the code in the abstract syntax tree and then unparses that back to code), Loader (handles the plugin), and Runner (executes the plugins). It works mainly with JavaScript but is also available for use with other languages like TypeScript, YAML, and Markdown. Let's look at comparisons with ESLint and where we may want to use it over ESLint.

    #### Advantages of Putout over ESLint

    ##### Applying fixes

    ESLint generally avoids applying complex [fixes that could change the runtime behavior](https://eslint.org/docs/developer-guide/working-with-rules#applying-fixes). On the other hand, Putout can make these more drastic code transformations that directly affect your codebase.

    ##### Minimalistic API

    Due to its plugin-first architecture, the initial API is kept as lean as possible, preventing unnecessary bloat and allowing the developer the choice of extension. Some plugin rules are also smaller than those available in ESLint, e.g., the [debugger rule](https://github.com/coderaiser/putout#%EF%B8%8F-in-doubt-about-using-putout). We can also use Putout with ESLint by allowing Putout to handle code transformations while ESLint handles any formatting broken after the code transformation. We can use the plugin [eslint-plugin-putout](https://github.com/coderaiser/putout/tree/master/packages/eslint-plugin-putout) to help with this integration.

    ### JSHint

    [JSHint](https://jshint.com/) was created as a more configurable version of JSLint; it was released in 2011 by John Crawford, and similar to ESLint, it helps us detect syntax errors in a JavaScript program. As it aims to be a configurable version of JSLint, and provides a plethora of options that can be disabled or enabled through a configuration file, which allows for some form of flexibility. Each available option is also adequately documented. JSHint comes with support for many frameworks such as JQuery, Mocha, and Node.js, and is also available as a plugin for many popular code editors.
    *   JSHint has basic support for ES6 syntax but no support for ESNext syntax; it also doesn't support JSX. This may be a deal-breaker, especially when considering it for use in more modern projects
    *   JSHint has no custom rule support
    *   JSHint has simple, clear, and concise documentation, especially around all the options available for use in a project
    *   Unlike JSHint, ESLint's error messages are pretty detailed and easy to understand because of the natural language used throughout all the messages
    *   If a rule is violated and needs to be fixed, JSHint doesn't show the name of the rule causing an error, making it more difficult to traceIn summary, for most of the scenarios we'll encounter, ESLint is a more mature and robust solution to consider among the two.

    ## Libraries to integrate with ESLint

    ### Prettier

    [Prettier](https://prettier.io/) is a code formatter. It provides support within the JavaScript ecosystem and specific other languages like Markdown and JSON. Prettier takes our code and reprints it from scratch, taking the line length into account and wrapping code where necessary. It strips away all default styling and ensures that the formatted code conforms to a consistent style. Prettier enforces a consistent code style across the entire codebase because it parses away any original styling and re-prints the parsed [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) (Abstract Syntax Tree) with its own rules. Unlike Rome, Prettier is not an outright alternative to ESLint, but we can configure Prettier for code formatting while using ESLint's code quality rules for catching bugs. Let's take a look at how to integrate prettier with ESLint.

    #### Integrating Prettier with ESLint

    I must admit that many guides are available on the internet for configuring Prettier to work with ESLint. This typically varies based on the JavaScript framework and project environment, but we'll look at a straightforward approach to integrating both in a vanilla JavaScript application. The first thing to do is install ESLint and Prettier for your code editor. For VS Code editor, we can find the extensions for ESLint and Prettier on the VS Code extensions marketplace. Next, we'll have to install three packages; type the following command in the terminal:

    ```shell
npm install --save-dev eslint eslint-config-prettier eslint-plugin-prettier
```

    The [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) package disables all ESLint rules that might conflict with Prettier. This lets us use ESLint configurations without letting it get in the way when using Prettier. We can then use the [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) package to integrate Prettier rules into ESLint rules. Finally, we must set the Prettier rules in the ESLint configuration file. Add the following configuration to the `.eslintrc` file in the root directory of the application:

    ```js 
    { 
     "extends": ["prettier"],
     "plugins": ["prettier"],
     "rules": { 
     "prettier/prettier": ["error"]
     },
    }
```

    And with that, we should be able to use Prettier with ESLint in our project seamlessly, and there shouldn't be any problem concerning rule conflicts between both libraries.

    ### Babel

    [Babel](https://babeljs.io/) is a JavaScript compiler mainly used to transform code from later ECMAScript versions (ES6+) to earlier ECMAScript versions, so it provides backward-compatible versions for current and older browsers or environments. We can use [Babel](https://blog.logrocket.com/babel-vs-typescript/) to transform syntax, provide a polyfill for unavailable features in the target environment, and source code transformations. Babel supports the latest ECMAScript features through syntax transformers; they allow us to use the newest syntax without waiting for browser support. Like Prettier, Babel isn't an alternative to ESLint but can leverage ESLint's linting features to provide our application with a much more robust set of features.

    #### Integrating Babel with ESLint

    ESLint's default parser and rules only support the latest final ECMAScript standard and [do not work on experimental features](https://github.com/eslint/eslint/blob/a675c89573836adaf108a932696b061946abf1e6/README.md#what-about-experimental-features). Therefore, we have to use an npm library - [@babel/eslint-parser](https://www.npmjs.com/package/@babel/eslint-parser) - to run ESLint on valid Babel code. Let's look at a simple way to set up this library in an existing Babel project. Head over to the terminal and run this command to install the library:

    ```shell 
npm install eslint @babel/eslint-parser --save-dev
    ```

    Once again, when the installation completes, go to the `.eslintrc.js` file (this is typically where we'd configure ESLint) and set this as the preferred parser:

    ```js 
module.exports = {
     parser: "@babel/eslint-parser",
    };
    ```

    Voila, we should now be able to use ESLint for linting our Babel code. There's also a guide in the [documentation](https://www.npmjs.com/package/@babel/eslint-parser) for advanced configurations.

    ### webpack

    [Webpack](https://webpack.js.org/) is a static module bundler for modern JavaScript applications - this means that it takes our JavaScript code and its dependencies and builds them into a single file. Webpack identifies all the dependencies (including images and other non-code files) in an application and builds a dependency graph internally. It then makes this into several bundles that can be loaded onto the browser. [Webpack](https://blog.logrocket.com/tree-shaking-json-files-webpack/) doesn't require any configuration by default to work, but it supports custom configurations for more complex projects. Let's look at how we can configure webpack to work with ESLint.

    #### Integrating webpack with ESLint

    Webpack has a robust plugin system that allows the community to provide otherwise unavailable features. To make this easy, we'll leverage a [popular community plugin](https://www.npmjs.com/package/eslint-webpack-plugin) to integrate webpack with ESLint. In an existing webpack project, head over to the terminal and run this command:

    ```shell 
npm install eslint-webpack-plugin --save-dev
    ```

    When the installation completes, add this option to the existing webpack configuration file:

    ```js 
const ESLintPlugin = require('eslint-webpack-plugin');
    module.exports = {
     // ...
     plugins: [new ESLintPlugin(options)], // plugin options
     // ...
    };
    ```

    The plugin configuration also takes specific options; we can find all the available options [here](https://github.com/webpack-contrib/eslint-webpack-plugin#options). It's that straightforward to integrate webpack with ESLint!

    ## Conclusion

    That's all! We learned about linters, code formatters, and also looked at some popular libraries that provided such functionalities. We were also able to go in-depth into some of the alternatives to ESLint and finally looked at how ESLint can be integrated with some of these libraries to provide us with a more robust set of functionalities.