Integrating ESLint into an Existing Codebase

Have you ever turned on ESLint and been faced with thousands of lines of red-highlighted code? I’ve been there. I was recently tasked with adding ESLint to a large codebase so we could enable linting in our CI pipeline.

The developers who owned the project were not very familiar with Javascript or ESLint, and I would only be on the project for a few more weeks before handing it off to them. Therefore, the introduction of ESLint to the codebase had to be slow, transparent, and easy to continue integrating after I was no longer on the project.

Here are some steps I took to make sure the process was as headache-free as it could be.

1. Identify low-hanging fruit, and take care of it first.

This could be as simple as running ESLint from the command line with its --fix flag to fix as many problems as possible.

The issue in my case? The codebase I was working on made heavy use of globals. Having ESLint fix all auto-fixable problems would have removed several global variables, as they were marked as unused. Make sure you identify any issues like this within your codebase before attempting to auto-fix.

2. Determine which rules to turn off temporarily; organize them.

When using ESLint, the end goal should be to have as few rules turned off as possible. Any cases where an exception needs to be made should be done on a line-by-line basis, not globally.

Of course, this may not be possible right off the bat. To avoid one big pull request with lots of regression testing, I did some combing through the codebase. Afterward, I determined which issues were fixable without heavy refactoring or team consultation and which ones were not.

Those that were not easily fixable had their associated ESLint rules turned off for the time being. I then split the disabled rules into a few categories, including:

  • Rules related to code style. This was especially important since I was ultimately going to be handing the project off. To prevent any developer friction, I wanted to be sure that we reached a consensus on style before enabling these.
  • Rules related to the usage of var. The codebase made almost exclusive usage of var instead of const or let. This directly or indirectly caused several other problems. All rules that could be turned back on once var had been completely removed from the codebase were grouped together.
  • Rules related to the usage of globals. As mentioned above, the app’s heavy use of globals made applying many of ESLint’s rules difficult. My goal was the complete removal of globals, but for the time being, I turned off rules that were difficult to enforce due to global usage.

3. Enforce the use of ESLint among the team.

There’s no point in doing any of the above if nobody else on the team is going to use ESLint. Make sure everyone understands its importance. If there are any rules that you feel may cause some extra friction, learn the “why” behind them so you can defend their use.

This is also where the above tips become particularly helpful. Making ESLint simple will prevent situations where developers feel that it’s making their work more difficult. Slow implementation and lots of communication across the team can help make things work much more smoothly.

It may also be beneficial to have team members use an automatic formatted (like prettier) to fix some ESLint problems on save. In some code editors (like VSCode), it’s possible to set up ESLint to run on save (although this will not work in very large codebases). This can help prevent developer frustration as well.

While getting ESLint set up can feel like a huge task at first, breaking it up into small pieces will go a long way. Future developers on the project will thank you; having ESLint will help cut down on tech debt for years to come.