464

I am currently validating my JavaScript against JSLint and making progress on, it's assisting me to write better JavaScript - in particular in working with the Jquery library.

I have now come across JSHint, a fork of JSLint.
So I am wondering for web applications, which are very much JavaScript was driven, which is the better or most applicable validation tool to work against:

  • JSLint or JSHint?

I want to decide now on a validation mechanism and moving forward, use this for client side validation.

And Difference between jshint and jslint? Please explain in single javascript example.

Links:

  1. jshint- http://www.jshint.com/

  2. jslint- http://jslint.com/

Vikrant
  • 4,920
  • 17
  • 48
  • 72
amateur
  • 43,371
  • 65
  • 192
  • 320
  • 5
    How about [ESLint](http://eslint.org/)? Though it's imperfect: `Combine this with the previous 'var' statement` -> `Do not mix 'require' and other declarations`, paradox. – alexia Aug 11 '14 at 22:30
  • Related: http://www.scottlogic.com/blog/2011/03/28/jslint-vs-jshint.html – Pacerier Jan 27 '15 at 14:01
  • 8
    Here's a good [comparison of JavaScript listing tools: JSLint, JSHint, JSCS, and ESLint](http://www.sitepoint.com/comparison-javascript-linting-tools/) – ma11hew28 Sep 22 '15 at 13:48
  • 1
    Not a JS developer. But I found JSHint very useful during our code review process. I recommend it. – Chetan Vashistth Jul 15 '19 at 05:35

8 Answers8

376

TL;DR

Use JSLint if you're looking for a very high standard for yourself or your team, but bear in mind that it's not necessarily the standard, only a standard, some of which comes to us dogmatically from Doug Crockford.

If you want to be a bit more flexible or have some old pros on your team that don't buy into JSLint's opinions or are going back and forth between JavaScript and other C-family languages regularly, try JSHint.

Full version

Two articles with the reasoning behind the fork explain why JSHint exists:

  1. JSHint: A Community-Driven Fork Of JSLint

  2. Why I forked JSLint to JSHint

The idea behind JSLint is that it's community-driven rather than Crockford-driven. JSHint is generally more lenient (or at least configurable or agnostic) on a few stylistic and minor syntactical opinions that JSLint is a stickler for.

For example, if you think both 1. and 2. below are fine, or if you want to write code with one or more of 1.'s aspects that aren't available in 2., JSHint is for you. If you think 2. is the only correct option, use JSLint. I'm sure there are other differences, but this highlights a few.

  1. Passes JSHint out of the box - fails JSLint

    (function() {
      "use strict";
      var x=0, y=2;
      function add(val1, val2){
        return val1 + val2;
      }
      var z;
      for (var i=0; i<2; i++){
        z = add(y, x+i);
      }
    })();
    
  2. Passes Both JSHint and JSLint

    (function () {
        "use strict";
        var x = 0, y = 2, i, z;
        function add(val1, val2) {
           return val1 + val2;
        }
        for (i = 0; i < 2; i += 1) {
            z = add(y, x + i);
        }
    }());
    

I find the JSLint code more visually appealing. The only features of it that I disagree with are its hatred of more than one var declaration in a function and of for-loop var i = 0 declarations, and some of the whitespace enforcements for function declarations.

A few of the whitespace things that JSLint enforces are not necessarily bad but are just out of sync with some pretty standard whitespace conventions for other languages in the family (C, Java, Python, etc.) often followed as conventions in Javascript as well. Since I'm writing in various of these languages throughout the day and working with team members who don't like Lint-style whitespace in our code, I find JSHint to be a good balance. It catches legitimate bugs and very badly formed code, but doesn't bark at me like JSLint does (sometimes, in ways I can't disable) for the stylistic opinions or syntactic nitpicks that I don't care for.

A lot of good libraries aren't Lint'able, which to me demonstrates that there's some truth to the idea that some of JSLint is just about pushing one version of "good code" (which is, indeed, good code). But then again, the same libraries (or other good ones) probably aren't Hint'able either, so, touché.

Aryan Beezadhur
  • 4,503
  • 4
  • 21
  • 42
B Robster
  • 40,605
  • 21
  • 89
  • 122
  • For more insight into why JSLint hates vars declared anywhere besides the top of the function, all together, and a bit of insight of why the lint/hint divide exists, here's an interesting github thread. github.com/douglascrockford/JSLint/issues/17 – B Robster May 26 '12 at 07:03
  • 1
    To sum up the reasoning, var declarations (but not their definitions) get moved to the top of a function when your js gets parsed, so there could theoretically be some type of issue come up if you don't realize this. http://stackoverflow.com/questions/4646455/jslint-error-move-all-var-declarations-to-the-top-of-the-function . Its something to keep in mind, but I haven't seen the case where it would create an error. If you try to re-declare a variable inside of a conditional or loop, thats a problem--but JSHint will catch this. Read Doug Crockford's Javascript The Good Parts, its awesome. – B Robster Jun 22 '12 at 15:32
  • 5
    Re-declaration is never a syntax error (according to ECMAScript they are silently ignored). The only logical issue is if you unintentionally eclipse a non-local variable. I think I would (and do) redeclare iteration varaibles in `for(var i = 0; ...; i++)` loops every time I write them, just so the loop is self-contained. I also recently commented elsewhere on this type of advice: http://addyosmani.com/blog/javascript-style-guides-and-beautifiers/comment-page-1/#comment-16346 and http://addyosmani.com/blog/javascript-style-guides-and-beautifiers/comment-page-1/#comment-16162 – Lee Kowalkowski Jun 22 '12 at 21:33
  • 12
    ...I must admit, I have been disappointed with the unprofessional quality of the advice that I have recently seen proliferated with respect to coding styles for JS (and CSS too, incidentally). It's as if the infatuation with a specific language has overridden the needs of non-expert practitioners (i.e. the target audience). This is such a shame considering they need good advice, and will blindly follow and perpetuate whatever is touted as best practice, without knowing any better. Often it is incompatible with other standards adopted by more established user-communities for other languages. :( – Lee Kowalkowski Jun 22 '12 at 22:05
  • 1
    One thing I've recently noticed: code written in Dreamweaver now fails JSLint because each indented line gets a "Use spaces, not tabs" and "Unsafe character" error. Dw's default indent is 4 spaces to a tab and it passes JSHint, and old scripts that used to pass JSLint now fail, so I have to think JSLint decided to be a stickler on this particular point. I'm switching to JSHint for this reason. – Jeremy Schultz Dec 17 '12 at 00:54
  • 68
    @LeeKowalkowski The reason that JSLint discourages `for (var i = 0; ...; i++)` is because it **does not** make the loop self contained. The scope of `i` is the function. The syntax looks like it is creating a block scope, but it is not and that leads the less experienced JavaScript programmers and people writing in multiple languages to misunderstand the scope of a variable and that can result in subtle bugs. Many of us (myself included) may not like how it looks to put all the declarations up top, but it is a good reminder that JavaScript does not have block scope. – Mark Evans May 14 '13 at 19:20
  • 25
    @MarkEvans It's self contained from the view that if you moved just the loop to another function, `i` will not accidentally become global. The fact that `i` is function scoped not block scoped is not a good enough reason to declare variables at the top, variables should always be declared as close to where they are used as possible (http://programmers.stackexchange.com/questions/56585/where-do-you-declare-variables-the-top-of-a-method-or-when-you-need-them). – Lee Kowalkowski May 15 '13 at 13:33
  • 3
    @LeeKowalkowski Sorry to be a pain, but the [highest voted answer](http://programmers.stackexchange.com/a/56590) in the link you provided is arguing that it improves [Resource Acquisition Is Initialization](http://en.wikipedia.org/wiki/RAII), and that it "keeps the scope tight" and helps the optimizer. Neither of these points is relevant to JavaScript. In JavaScript the only reason to declare the variable close to where it is used or inside a for loop is because it's aesthetically pleasing. As far as being able to copy and paste the for loop, JSHint or JSLint will catch the global variable. – Mark Evans Jun 07 '13 at 20:48
  • 17
    @MarkEvans I think you're focussing too much on language implementation details. Programming standards should be for humans, not compilers. Reliance on a static code analysis tool to catch common pitfalls is no replacement for adopting good habits that avoid them in the first place. I can't fathom a reason why an iterator variable for a simple loop should be declared any distance away from the loop that requires it. Many coding standards for other languages say declare variables as close as to where they are used as possible, for readability. I haven't seen a good reason not to do this in JS. – Lee Kowalkowski Jun 09 '13 at 09:01
  • ..also a lot of the information in that questions answers are in the answer's comments, that's where there's general consensus that declaring closest is preferable. – Lee Kowalkowski Jun 09 '13 at 09:02
  • 1
    @LeeKowalkowski Errors in JSLint are based on real programming mistakes in the wild. Proof-reading code for silly mistakes is best done mechanically, and if I have to adopt one or two really rather painless conventions to help the linter, then I'm all for that. And if you are writing short functions then all declarations will be near where they are used anyway. I used to have a whole bunch of JSLint config options that removed various checks so that it would pass code in my style. And one by one I added the checks back in each time I made a mistake that JSLint would have caught. – 1983 Jul 11 '13 at 10:42
  • 3
    @NagaJolokia what are you referring to? Placing variables as close to where they are used prevents programming mistakes in the wild too. I'm sorry, but placing them at the top of a function has no basis, and its justification is "that's what JavaScript does internally" not because it reduces errors, I've seen no evidence of it - well not good enough, programming style is for people, not for compilers. – Lee Kowalkowski Jul 11 '13 at 11:14
  • ...referencing uninitialised variables is the actual 'real-world' programming error, PHP has this as a complier warning, and CheckStyle in Java will report this too. – Lee Kowalkowski Jul 11 '13 at 11:25
  • JSLint and JSHint warn about using undeclared vars. – 1983 Jul 11 '13 at 11:29
  • 4
    @LeeKowalkowski It's not about style, it's about preventing silly errors which can be caught mechanically. Having a var declaration in a for-loop does *not* make it self contained. If you are copying it into a function which already uses i then there's a chance you've just introduced a bug. (Ideally we don't copy and paste code anyway). Most of the time there won't be a problem with smart code. Linters are for the dumb code, and I've written my fair share of that. I'd just rather spend my time debugging the more intelligent errors. – 1983 Jul 11 '13 at 11:30
  • Also: most for-loops can be replaced with Array.prototype.forEach with proper scoping for the loop index. – 1983 Jul 11 '13 at 11:36
  • @NagaJolokia I'll give you a chance to save yourself some embarrassment. Do you think that declaring and initialising an iterator variable within a typical simple for() statement is so dangerous that it must be fixed before lint processing can complete? Anybody that does is not demonstrating sufficient programming experience to advise others of best practices. Because the reality is that it is perfectly safe. – Lee Kowalkowski Jul 11 '13 at 11:38
  • Undeclared doesn't mean uninitialised, that's a scoping pitfall, not the same problem. – Lee Kowalkowski Jul 11 '13 at 11:41
  • 11
    Using an iterator variable outside of a loop is the thing a linter ought to check for. – Lee Kowalkowski Jul 11 '13 at 11:48
  • 2
    We're talking about declaration, not initialisation. And it isn't 'perfectly safe' -- in fact you gave an example of where this goes wrong in your first comment. Anyway, this is not a black and white issue. What goes in a linter is partly a matter of opinion, and there's room for more than one opinion here. Both styles have their adherents, and I respect the opinion of both camps. – 1983 Jul 11 '13 at 16:46
  • 1
    +1 "But its not necessarily THE standard, just A standard" – Bobby Cannon Apr 23 '14 at 12:58
  • 4
    I switched to JSLint. I prefer JSLint because it forces me to BECOME a better JavaScript programmer and to learn more about the language. JSHint made me FEEL like a good JavaScript programmer. JSLint made me start reading more about JavaScript and it made me realize how many things I was doing wrong. JSHint was created because some programmers are writing JavaScript like Java, and JSLint was complaining. I want to be a good JavaScript programmer, not Java programmer who knows a thing or two about JavaScript. – Goran Vasic Nov 27 '14 at 16:33
  • 2
    interesting to see that with ES2015 that Javascript is now moving to be more like Java with the preferred use of let over var and block scoping. Looks like function scope wasn't a great idea. – BlackICE Mar 28 '16 at 02:58
  • i really like the concise well-written paragraph at the start. **in particular i really like how you emphasize "[using jslint is] not necessarily THE standard, just A standard, some of which comes to us dogmatically from a javascript god named Doug Crockford. If you want to be a bit more flexible, or have some old pros on your team".** I used to be very dogmatic/critical-of-"non-standard"-code... but that hindered my ability to work with others and work on large code projects. It is very important to not get too dogmatic about lint programs like jslint. – Trevor Boyd Smith Jan 29 '19 at 16:13
160

[EDIT]
This answer has been edited. I'm leaving the original answer below for context (otherwise the comments wouldn't make sense).

When this question was originally asked, JSLint was the main linting tool for JavaScript. JSHint was a new fork of JSLint, but had not yet diverged much from the original.

Since then, JSLint has remained pretty much static, while JSHint has changed a great deal - it has thrown away many of JSLint's more antagonistic rules, has added a whole load of new rules, and has generally become more flexible. Also, another tool ESLint is now available, which is even more flexible and has more rule options.

In my original answer, I said that you should not force yourself to stick to JSLint's rules; as long as you understood why it was throwing a warning, you could make a judgement for yourself about whether to change the code to resolve the warning or not.

With the ultra-strict ruleset of JSLint from 2011, this was reasonable advice -- I've seen very few JavaScript codesets that could pass a JSLint test. However with the more pragmatic rules available in today's JSHint and ESLint tools, it is a much more realistic proposition to try to get your code passing through them with zero warnings.

There may still occasionally be cases where a linter will complain about something that you've done intentionally -- for example, you know that you should always use === but just this one time you have a good reason to use ==. But even then, with ESLint you have the option to specify eslint-disable around the line in question so you can still have a passing lint test with zero warnings, with the rest of your code obeying the rule. (just don't do that kind of thing too often!)


[ORIGINAL ANSWER FOLLOWS]

By all means use JSLint. But don't get hung up on the results and on fixing everything that it warns about. It will help you improve your code, and it will help you find potential bugs, but not everything that JSLint complains about turns out to be a real problem, so don't feel like you have to complete the process with zero warnings.

Pretty much any Javascript code with any significant length or complexity will produce warnings in JSLint, no matter how well written it is. If you don't believe me, try running some popular libraries like JQuery through it.

Some JSLint warnings are more valuable than others: learn which ones to watch out for, and which ones are less important. Every warning should be considered, but don't feel obliged to fix your code to clear any given warning; it's perfectly okay to look at the code and decide you're happy with it; there are times when things that JSlint doesn't like are actually the right thing to do.

Spudley
  • 166,037
  • 39
  • 233
  • 307
  • 3
    The best part of jsHint is that it have flags for accepting jQuery and isn't annoying/strict as jslint. E.g.: `for (i = 0; i < dontEnumsLength; i++)` throws `Unexpected '++'` where it's ok. etc. – RaphaelDDL Jul 09 '13 at 18:02
  • 2
    Please, don't ignore rules, this is the worst thing that you could do with linter. Just setup it, or if you cann't do it, change. JSHint and JSCS combination is fantastic – AuthorProxy Apr 09 '15 at 15:07
  • JSHint says "Expected an assignment or function call and instead saw an expression." to a ternary used for operations only. Mozilla documentation: says "You can also use ternary evaluations in free space in order to do different operations". https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator @AuthorProxy I'm going for Mozilla and ignoring JSHint. Sorry. – dewd Apr 24 '15 at 14:52
  • 1
    By now it looks like ESLint is the direction the industry is headed overall, along with popular configs like airbnb. – jinglesthula May 16 '18 at 22:31
63

There is an another mature and actively developed "player" on the javascript linting front - ESLint:

ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code. In many ways, it is similar to JSLint and JSHint with a few exceptions:

  • ESLint uses Esprima for JavaScript parsing.
  • ESLint uses an AST to evaluate patterns in code.
  • ESLint is completely pluggable, every single rule is a plugin and you can add more at runtime.

What really matters here is that it is extendable via custom plugins/rules. There are already multiple plugins written for different purposes. Among others, there are:

And, of course, you can use your build tool of choice to run ESLint:

ma11hew28
  • 121,420
  • 116
  • 450
  • 651
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • 1
    The value of having a linter that runs in your editor as you type can't be understated. ESLint is used this way extensively. I haven't ever heard of JSLint or JSHint editor support (1 anecdotal data point). – jinglesthula May 16 '18 at 22:33
18

I had the same question a couple of weeks ago and was evaluating both JSLint and JSHint.

Contrary to the answers in this question, my conclusion was not:

By all means use JSLint.

Or:

If you're looking for a very high standard for yourself or team, JSLint.

As you can configure almost the same rules in JSHint as in JSLint. So I would argue that there's not much difference in the rules you could achieve.

So the reasons to choose one over another are more political than technical.

We've finally decided to go with JSHint because of the following reasons:

  • Seems to be more configurable that JSLint.
  • Looks definitely more community-driven rather than one-man-show (no matter how cool The Man is).
  • JSHint matched our code style OOTB better that JSLint.
lexicore
  • 42,748
  • 17
  • 132
  • 221
13

Foreword: Well, that escalated quickly. But decided to pull it through. May this answer be helpful to you and other readers.

I got a bit carried away here

Code Hinting

While JSLint and JSHint are good tools to use, over the years I've come to appreciate what my friend @ugly_syntax calls:

smaller design space.

This is a general principle, much like a "zen monk", limiting the choices one has to make, one can be more productive and creative.

Therefore my current favourite zero-config JS code style:

StandardJS.

UPDATE:

Flow has improved a lot. With it, you can add types to your JS with will help you prevent a lot of bugs. But it can also stay out of your way, for instance when interfacing untyped JS. Give it a try!

Quickstart / TL;DR

Add standard as a dependency to you project

npm install --save standard

Then in package.json, add the following test script:

"scripts": {
    "test": "node_modules/.bin/standard && echo put further tests here"
},

For snazzier output while developing, npm install --global snazzy and run it instead of npm test.

Note: Type checking versus Heuristics

My friend when mentioning design space referred to Elm and I encourage you to give that language a try.

Why? JS is in fact inspired by LISP, which is a special class of languages, which happens to be untyped. Language such as Elm or Purescript are typed functional programming languages.

Type restrict your freedom in order for the compiler to be able to check and guide you when you end up violation the language or your own program's rules; regardless of the size (LOC) of your program.

We recently had a junior colleague implement a reactive interface twice: once in Elm, once in React; have a look to get some idea of what I'm talking about.

Compare Main.elm (typed) ⇔ index.js (untyped, no tests)

(ps. note that the React code is not idiomatic and could be improved)

One final remark,

the reality is that JS is untyped. Who am I to suggest typed programming to you?

See, with JS we are in a different domain: freed from types, we can easily express things that are hard or impossible to give a proper type (which can certainly be an advantage).

But without types there is little to keep our programs in check, so we are forced to introduce tests and (to a lesser extend) code styles.

I recommend you look at LISP (e.g. ClojureScript) for inspiration and invest in testing your codes. Read The way of the substack to get an idea.

Peace.

wires
  • 4,718
  • 2
  • 35
  • 31
13

I'd make a third suggestion, Google Closure Compiler (and also the Closure Linter). You can try it out online here.

The Closure Compiler is a tool for making JavaScript download and run faster. It is a true compiler for JavaScript. Instead of compiling from a source language to machine code, it compiles from JavaScript to better JavaScript. It parses your JavaScript, analyzes it, removes dead code and rewrites and minimizes what's left. It also checks syntax, variable references, and types, and warns about common JavaScript pitfalls.

Jeff Foster
  • 43,770
  • 11
  • 86
  • 103
  • 4
    What does the Closure Compiler pick up that the linter does not? – James McMahon Jul 25 '12 at 19:59
  • 4
    I don't see a single warning generated by this tool, when it surely should. JSLint and JSHint produce so many warnings for the same input, that they both give "too many errors". – wallyk Aug 29 '12 at 19:14
  • 6
    we used closure on a recent project and would not do it again. the linter can't be configured to turn of certain checks (many of which are things you won't care about) and the compiler really only pays off if you are working exclusively with closure-friendly libraries (of which there really aren't any outside of google's). – Robert Levy Mar 05 '13 at 13:52
  • 4
    This is not referring to Google Closure Comepiler per se, but Google's tools should always be looked at with a grain of salt. They are built for solving particular Google's goals, and they may not coincide with your goals. – Pacerier Jan 27 '15 at 13:57
  • @RobertLevy thanks for commenting on your experience you had... i was reading the google style guide for javascript and it recommended closure-compiler as it's lint program. but now i see there are others like jslint and jshint – Trevor Boyd Smith Jan 29 '19 at 16:17
  • re @wallyk i also did not see any warnings from google closure compiler when i ran it against my javascript. that is because the program's first usage is for javascript optimization/minimizing-code-size... and SECOND usage is for code lint. to enable lint you have to use the option `--checks_only --warning_level=VERBOSE`. when you use those options you will get the lint output that you desire. but as @RobertLevy said the lint settings are not so configurable. – Trevor Boyd Smith Jan 29 '19 at 16:23
  • @TrevorBoydSmith my comment was from almost 6 years ago :) these days, the cool kids use ESLint for javascript. the *really* cool kids code in typescript which currently has it's own linter but that will soon be decommissioned in favor of TS support in ESLint. – Robert Levy Jan 30 '19 at 16:54
  • @RobertLevy thanks for the tip on `eslint`. [google trends agrees that `eslint` is the most popular search term among: jslint, jshint, eslint](https://trends.google.com/trends/explore?date=all&geo=US&q=jslint,jshint,eslint). – Trevor Boyd Smith Jan 30 '19 at 17:52
8

Well, Instead of doing manual lint settings we can include all the lint settings at the top of our JS file itself e.g.

Declare all the global var in that file like:

/*global require,dojo,dojoConfig,alert */

Declare all the lint settings like:

/*jslint browser:true,sloppy:true,nomen:true,unparam:true,plusplus:true,indent:4 */

Hope this will help you :)

Vikash Pandey
  • 5,407
  • 6
  • 41
  • 42
1

There is also an another actively developed alternative - JSCS — JavaScript Code Style:

JSCS is a code style linter for programmatically enforcing your style guide. You can configure JSCS for your project in detail using over 150 validation rules, including presets from popular style guides like jQuery, Airbnb, Google, and more.

It comes with multiple presets that you can choose from by simply specifying the preset in the .jscsrc configuration file and customize it - override, enable or disable any rules:

{
    "preset": "jquery",
    "requireCurlyBraces": null
}

There are also plugins and extensions built for popular editors.

Also see:

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195