Deprecation of formatting rules

The next minor release of ESLint will deprecate core formatting rules. We recommend you use a source code formatter instead.

In ESLint v8.53.0, scheduled to be released on Friday, November 3, 2023, we will formally deprecate our formatting rules. Formatting rules are those rules that simply enforce code conventions around spacing, semicolons, string formats, etc. For a variety of reasons, which are discussed in this post, this is the right decision for ESLint going forward. However, to understand how we got here, it’s helpful to look backward for a moment.

Background

When ESLint was initially released in 2013, the JavaScript ecosystem was embroiled in a debate about whether or not source code formatting should be part of a linter. JSLint, the original JavaScript linter, heavily encoded its author’s formatting preferences into the tool. Those preferences were carried over and loosened a bit in JSLint’s successor, JSHint, but by 2013, JSHint had announced that it was deprecating its formatting options and would be removing them in the next major release. While the options were never removed, they still show this warning:

Warning This option has been deprecated and will be removed in the next major release of JSHint.

JSHint is limiting its scope to issues of code correctness. If you would like to enforce rules relating to code style, check out the JSCS project.

The JSCS project was born to cater to the growing desire of JavaScript developers to format their code in more specific ways. Appearing in the same year as ESLint, there was a bit of an experimentation period as people tried using different combinations of JSHint, JSCS, and ESLint to achieve their linting and formatting needs.

Early on, I thought the only way for ESLint to reasonably compete with JSHint was to ensure that all available JSHint rules had ESLint equivalents. While the strength of ESLint was (and still is) in creating custom rules, I didn’t think ESLint would get much adoption if everyone had to recreate the JSHint rules for themselves. My initial plan was to make a couple dozen core rules and then leave the rest to be implemented as plugins.

As time went on, ESLint received more and more requests to add formatting and stylistic rules to the core. Many of the requests mentioned that they didn’t want to use two tools (ESLint and JSCS) on their code and if ESLint could do everything that JSCS did, they could drop JSCS and just use ESLint. And so, now that ESLint had a team, we focused on getting feature parity to support this use case. Eventually, we did such a good job that JSCS usage dropped and we merged JSCS into ESLint.

What we didn’t know at the time was that JSHint had the right idea, and although ESLint had become the dominant linter (and source code formatter) for JavaScript, we had also signed up for a lot of work.

JavaScript’s explosion and the maintenance burden

In the ensuing years, and especially spurred on by ECMAScript 6 and the growth of React, the way people were writing JavaScript was changing dramatically. Increasingly popular style guides like Airbnb and Standard encouraged JavaScript developers to get more specific about how their code was written. As a result, ESLint was inundated with requests for exceptions and options on formatting rules. Over the last ten years, we’ve seen all manner of bizarre styles accompanied by requests to enforce them in ESLint core rules. And every time new syntax is introduced, we get a flurry of requests to update existing rules and implement new rules.

As we approached 300 rules in the core, we tried to reduce the maintenance burden by freezing stylistic rules so that we were no longer chasing down corner cases to support everyone’s personal preferences. That helped somewhat, but not enough.

  • Rule clashes. People expect that core rules will play nice with each other, meaning that no two rules should flag the same problem nor will any two core rules give conflicting advice. While that was easy when there were less than 30 core rules, with 300 rules it became difficult, if not impossible, to achieve.
  • Unrealistic expectations. With a large core of formatting rules, users expected that every possible style guide should be achievable just with core rules and without involving plugins. This put more pressure on the team to continue adding options, which also increased the size of the core.
  • Effort vs. value misalignment. The maintenance burden of continuously adding new options and exceptions to support everyone’s style guides was falling on the ESLint team whereas the value was being extracted by a small number of users.
  • Opportunity cost. The more time we had to spend maintaining formatting rules, the less time we had to spend on things that are beneficial to large numbers of our users.
  • Lack of interest. While ESLint benefits from outside contributions, those contributors are just not interested to chasing down corner cases of spacing. The ESLint team, itself, prioritized these rules much lower than any other work, which often left issues open for extended periods of time.
  • Consistency issues. Because ESLint’s rules are designed to be atomic and not to have access to other rules, we would run into issues where it wasn’t possible to correctly fix an error because the information was in another rule. For example, if an autofix needs to add a new line of code, it would need to know how the file is indented in order to apply the correct fix. However, the indent rule controls indenting for ESLint, which meant that other rules needed to apply fixes without indentation and then trust that the indent rule would fix the indentation on a subsequent pass.

All of these problems continued to grow as ESLint got older, and we’re finally at a point where we just cannot keep up with them.

The deprecated rules

The following list contains all of the rules that will be deprecated in v8.53.0:

All of these rules will be deprecated as of the next release, but will not be removed until at least ESLint v10.0.0 (if not later). You can continue to use them although you may see deprecation warnings in the ESLint CLI.

What you should do instead

We recommend using a source code formatter instead of ESLint for formatting your code. Source code formatters are built to understand the entire file and apply consistent formatting throughout. While you might not have as much control over exceptions as with ESLint, the tradeoff is the simplicity and speed you’ll get vs. configuring ESLint with dozens of individual rules. There are two formatters that we recommend:

  • Prettier - a JavaScript-based formatter with support for formatting a large number of languages
  • dprint - a Rust-based formatter with support for a smaller set of languages

If the idea of using a dedicated source code formatter doesn’t appeal to you, you can also use @stylistic/eslint-plugin-js for JavaScript or @stylistic/eslint-plugin-ts for TypeScript. These packages contain the deprecated formatting rules from the ESLint core and typescript-eslint, respectively. The packages are maintained by Anthony Fu, who has decided to continue maintaining these rules going forward. If you’d like to continue using the rules mentioned in this post, then we recommend switching to these packages.

Conclusion

We know that a lot of people rely on ESLint for code quality and formatting purposes, and as such, we don’t take significant decisions like this lightly. Unfortunately, the way we’ve been doing things just won’t scale much further and we needed to make this change. The ubiquity and popularity of dedicated source code formatters made this decision somewhat easier, as was Anthony Fu volunteering to maintain the rules as a separate package. We hope that one of the available options mentioned in this post will ensure that people can continue formatting their source code in their preferred way.

The latest ESLint news, case studies, tutorials, and resources.

ESLint v9.1.1 released
1 min read

ESLint v9.1.1 released

We just pushed ESLint v9.1.1, which is a patch release upgrade of ESLint. This release fixes several bugs found in the previous release.

ESLint v9.1.0 released
2 min read

ESLint v9.1.0 released

We just pushed ESLint v9.1.0, which is a minor release upgrade of ESLint. This release adds some new features and fixes several bugs found in the previous release.

ESLint v9.0.0 released
12 min read

ESLint v9.0.0 released

We just pushed ESLint v9.0.0, which is a major release upgrade of ESLint. This release adds some new features and fixes several bugs found in the previous release. This release also has some breaking changes, so please read the following closely.