Managing Coding Style in JavaScript with eslint

I’m a big fan of linters, especially in the case of JavaScript.  Most languages are statically typed and have fairly well known and rigid formatting.  This allows consumers of the language to read source code and easily digest what it is doing.  Not so JavaScript.  Some of the code is so badly written that you have to run it to figure it out. Naturally, I want to avoid writing bad code, so the use of linters is mandatory.

JavaScript linters, including JSLint, JSHint and my favorite – ESLint, provide many functional benefits to you by statically analyzing your code.  They can uncover a slew of issues before you even run the code.  ESLint breaks down the rules (there are over 200 rules in the default set) into three major areas – potential errors, best practices and style. I use eslint because it supports ES2015 and React/JSX out of the box.

If you use an alternative, then you have:

There really is no good reason to NOT use a linter.

Let’s take a quick step back and go through how you use this.  Firstly, you need to install eslint:

npm install -g eslint

Then you need to create a configuration file.  I prefer my configuration file to be in JavaScript – it allows me to document the configuration so that I remember why I put a particular setting in there.  The filename of the configuration file is .eslintrc.js.  You can find my as a gist on The basics of this file are here:

var OFF = 0, WARN = 1, ERROR = 2;

module.exports = exports = {
    "env": {
        "es6": true,
        "browser": true,
        "commonjs": true

    "ecmaFeatures": {
        // env=es6 doesn't include modules, which we are using
        "modules": true

    "extends": "eslint:recommended",

    "rules": {
        // Put your overrides here

You can use the keywords OFF, WARN and ERROR instead of the numeric values in the rule overrides, as we will see later.
You can then override the default handling of any rules in
the rules section. You can run this by using:

eslint src

The eslint program looks for several config files, but the JavaScript version is the first one that it looks for. It will also look in parent directories for a suitable file, so you can set up your rules at the top of your project and have the settings work for all files. I tend to place my .eslintrc.js file in the src directory as my Gulpfile.js, tests and so on require different rules.

Back to those three areas. The first area is Possible Errors. Most of these are enabled as errors in the recommended set. You will probably want to override the ones that aren’t in the recommended set – they are useful.

The second set is Best Practices. I read the description of each rule in the set and made a judgement call on whether the rule would be an error or a warning or turned off. Most rules are simple. For example, I don’t want to ship a product with alert() calls, so I have the following override:

"no-alert": ERROR,

Some rules have additional information and you have to read the rule details for that information. An example of this is the accessor-pairs rule. This covers getters and setters. One of the things I like to do is have class properties written as accessors. This allows me to provide a “read-only” property by only specifying a getter. Thus my rule is:

"accessor-pairs": [ ERROR, {
    "getWithoutSet": false,
    "setWithoutGet": true

This says that I can have just a getter or a getter and a setter. I cannot have a setter without a getter. I prefer best practices to be errors by default and need to justify to myself why something should be a warning.

The final section is Stylistic. Pretty much every development group has a coding style guide. It goes into things about where curly-braces should be, what sort of quotes to use, how to name variables, whether to use tabs or spaces for indents and so on. This section (which is the bulk of the rules) allow you to enforce this coding style. In this section, I prefer things to be warnings and have to justify errors. The difference here is that the code will still work – it’s just coding style.

I run eslint before I do anything else on a compilation. I have two mechanisms for handling builds. In the first mechanism, I use the package.json to build the code and eschew a task runner. This is generally for smaller projects. In this case, I put the eslint call in the package.json scripts section, like this:

  "scripts": {
    "pretest": "eslint src test",
    "test": "mocha"

If I am doing a build, I’m usually using a task runner – gulp is my task runner of choice. In this case, I have a task to do the eslint for me:

var gulp = require('gulp'),
    eslint = require('gulp-eslint');

var config = {
    paths: {
        src: './src/**/*.js',
        dest: './dist'

gulp.task('lint', function () {
    return gulp.src([ config.paths.src, '!**/.eslintrc.js' ])

gulp.task('build', [ 'lint' ], function () {
    // my build process here

The gulp.src line explicitly ignores your .eslintrc file – it’s a circular reference and tends to not follow style, surprisingly.

There will come a time when you want to override a rule for a specific case. I always do something like the following when I do this:

// lint-disable: foobar is an external library (new-cap)
var x = new foobar(); //eslint-disable-line new-cap

Note two things here. Firstly, I say why the rule was disabled. This prevents any guessing on the part of people that come after me. I also prefix the the line with lint-disable so that I can easily grep the entire source tree for lint-disable to get all the lines. Secondly, I only disable the rule on one line. This is the preferred method.

Sometimes I need to disable a rule for a whole function; I use a block disable. This has to be even rarer and again needs to be documented:

/* eslint-disable id-length */
/* lint-disable id-length - the library foobar has this identifier */
function myfoo() {
  foobar.aReallyLongIdentifierUsedByFooBarIsObnoxiousButRequired = false;
/* eslint-enable id-length */

You should (and can easily) audit all the lint-disable lines and blocks on a regular basis.

So, how do I use eslint?

  • eslint the source before every build and test – fix errors
  • eslint the source before every check in – fix warnings
  • audit the source for lint-disable before every release

There are a few things more important than static analysis of your code, but it’s right up there with testing. You need to be linting your JavaScript code on a very regular basis. Automate your usage of eslint (or another JavaScript linter) so that it’s a part of your build process.