In today’s post, we answer the title question, and more. We start by defining the term “linter.” You’ll understand what this thing is and how it came to be. Then, we talk about the benefits of linters and proceed to talk about the different types of checks they offer.
Finally, we show you several examples of linters at your disposal, give some practical tips on how to get started, and wrap-up with a few final considerations.
Let’s get started.
What Is a Linter? A Brief Overview
Let’s start by defining what a linter is. As you’ve read in the introduction, a linter is a tool to help you improve your code. But in what ways does it do that? The answer is: by analyzing your source code looking for problems.
The term linter comes from a tool originally called “lint” that analyzed C source code. The computer scientist Stephen C. Johnson developed this utility in 1978 when he worked at Bell Labs.
Both the original lint tool, as well as earlier similar utilities, had the goal of analyzing source code to come up with compiler optimizations. Over time, lint-like tools started adding many other types of checks and verification.
However, as we’ve mentioned during the introduction, linters aren’t restricted to compiled languages. On the contrary: we could say that linters are way more valuable for interpreted languages since there’s no compiler to detect errors during development time.
Advantages of Linting
You’ve just learned the definition of linter. You now also know when this type of tool was invented, and by whom. You probably have by now at least a general idea of what a linter can do for your code. But in more practical terms, what are the benefits that this type of tool can provide? Here are some:
- Fewer errors in production
- Readable, maintainable and more consistent code
- Fewer discussions about code style and aesthetic choices during code reviews
- Objective measurement of code quality
- More secure and performant code
The next section covers some of the types of verifications that linters provide. After reading it, you’ll understand how linters provide the benefits above.
Types of Checks Linters Provide
As you’ve just read, the original lint tool analyzed code to enable optimizations for compilers, but over time, more advanced and complete tools were released. Nowadays, we have myriad different linters, which provide many types of checks. Let’s quickly go through some of them.
One way to accomplish this is to use pre-commit hooks that prevent users from pushing their code when the linter verification indicates there are issues with the code.
Code Standards Adherence
Another vital type of check that linters provide is adherence to coding standards. Some people might dismiss this as a purely aesthetic concern, but they’d be wrong. Having a single consistent coding style is beneficial for decreasing the cognitive load of reading, understanding, and maintaining code. A codebase that has a consistent code style will be easier to understand, and the developers that use it will be less likely to introduce bugs.
That’s why there are linters that specialize in verifying codebases for adherence to code styles. Some tools are opinionated, i.e. they come with a pre-defined set of rules and conventions that can’t be changed. On the other hand, there are tools that can be highly configurable, allowing the user to adapt the tool to their preferred coding styles.
Potential Problems (a.k.a. Code Smells)
Code smells are signs that something might be wrong with your code. It’s amazingly useful to have a tool to detect those signs automatically, so you can investigate them further, if necessary.
For instance, many people—including me—consider long functions to be a code smell. So, you could configure your linter to detect functions that are longer than a given number of lines.
Another often cited code smell is code that is too complex. But we’re not talking about complexity in a subjective way, but a very objective one. Cyclomatic complexity is a useful code metric that represents the number of possible execution paths inside a function. Linters can calculate the cyclomatic complexity of your functions and flag those that are higher than a certain threshold.
Last, but not least, we have security, which is, without a doubt, the most critical facet of a modern application, especially a web app. Get it wrong, and the consequences can be catastrophic, not only in regards to money and reputation but even legal ones (think GDPR and similar regulations.)
Fortunately, this is another area where linters can be of help since there are tools that provide important security verifications.
Understanding Static Analysis
We’ve explained what linters are and why they’re useful. Also, we’ve covered the main types of linters. You’re now ready to learn about some examples of linting tools for a variety of uses and target programming languages.
Before we get there, though, let’s take a brief digression to talk about static analysis, since this term appears in the next section, and we haven’t defined it yet.
So, what’s static analysis? You can think of static analysis as a pre-run debug. Static analysis consists of using tools that analyze your source code looking for errors, lack of adherence to rules or conventions, or other potential problems.
The next section shows examples of linters categorized according to the type of verification they perform. Entries categorized under static analysis refer mostly to the first and third types of linters listed in the above section.
Examples of Linters
Let’s now briefly mention some examples of linters. We’ll show examples for different programming languages, categorized by the type of checking they provide. Keep in mind that some tools might offer more than one type of verification, so that’s the reason some tools appear in more than one category.
Linters for Static Analysis
Linters for Security
Linters for Coding Conventions / Coding Formatting
First things first: let’s install the linter. ESLint is installed via npm, which means you must have Node.js installed. If you don’t already have it, download it and install it so we can continue.
With Node.js installed, we’re ready to install ESLint via npm.
To install the tool globally, run the following command:
npm install eslint --global
However, this isn’t the approach recommended in their documentation. Instead, you should probably install ESLint on a per-project basis. So, start by creating a directory for your project:
Then, cd into the directory and run the command below to create a package.json file (it will be needed down the road.)
Npm will ask you several questions. Just press enter to use the default answer for all of them. After that, you’ll be ready to add ESLint to your project by running this:
npm install eslint --save-dev
Initializing and Setting Up ESLint
After that you’ll be ready to initialized ESLint, by running:
npx eslint --init
When you run the command above, ESLint will ask you for what do you want to use it for. The options are: to check syntax only, to check syntax and find problems, and to check syntax, find problems and enforce code style.
Let’s go with the last option. Use the arrow keys to change options and ENTER to confirm. ESLint will then want to know which types of modules your project use. The answers are:
- CommonJS Modules
- None of these
- None of these
In our case, let’s pick the “none” option. The next question is a “yes/no” question: does your project use Typescript? Press “N” for no. After that, it asks you whether your code runs in the browser or in Node.
ESLint then asks you how to choose a way to define a code style for your project. It offers you three possibilities: using a popular style guide, answering questions about your style preferences, or inspecting your .js files. Choose the first option. Then you’ll be asked to choose between three styles: AirBNB, Standard, and Google. For this tutorial, let’s pick Google.
ESLint will then ask which format you prefer for your configuration. Pick YAML. Finally, when asked if you wish to download the selected code style using npm, answer “yes.”
Using ESLint to Check a File
After the download is complete, you’ll be ready to use ESLint to check a file. But for that, you need a file to check. If you happen to have a .js file hanging around somewhere, copy it into your project directory. Alternatively, you can clone this repository, containing a single file, and use it for your testing.
To check a file, you use the following command:
npx eslint path-to-your-file.js
This is the result I get from running the command targeted at the greeting.js file you can download from the repository on GitHub:
2:3 error Missing JSDoc comment require-jsdoc
3:1 error This line has a length of 86. Maximum allowed is 80 max-len
10:4 error Unexpected 'this' no-invalid-this
✖ 3 problems (3 errors, 0 warnings)
As you can see, I’ve got three errors and no warnings.
What Is a Linter? A Great Tool for Your Toolbelt
In this post, we’ve examined the concept of a linter tool. Now you have a solid idea of what linters are and why you should adopt one. Additionally, you’ve learned about different types of linter tools and examples of each category, targeting several different programming languages.
What are the next steps? There are several things you can learn how to do next:
- Disable rules
- Enable a rule as a warning or an error
- Integrate linting into your build process
- Advanced configuration option
- Create your custom rules
You can also, of course, experiment with other linters. Just because we’ve picked ESLint for this guide, that doesn’t mean you should get stuck with it.
Finally, don’t forget that linting, while amazingly valuable, is just another weapon in your arsenal. You shouldn’t forget about automated testing, code review, refactoring, and many other practices, techniques, and tools at your disposal in the never-ending fight against chaos in your codebase.
And among all the practices, techniques, and tools you can leverage to make your codebase better, we can’t help but single-out end-to-end testing, which is an often-overlooked type of testing. And that’s a shame. With the right tool to help you out, quality end-to-end testing can be a powerful ally in your struggle against code entropy.