JavaScript: The Semicolon Debate

By May 25, 2016JavaScript

Emacs or Vim? Tabs or spaces? Android or iOS? In the world of technology, there are always some contentious topics that are hotly debated, yet ultimately come down to a matter of taste, will therefore never be truly settled, but will nevertheless provide fuel for the fire for years to come. I recently learned of another such topic that I want to weigh in on: semicolon-free JavaScript. I actually stumbled across this debate while browsing the configuration options for JSHint. There it was, “asi“, complete with a description that just invited further investigation. I did my research and read posts on both sides of the debate. I learned that ASI (Automatic Semicolon Insertion) is actually part of the JavaScript language specification, so its behavior is completely standard across all browsers. I learned that one of the commonly referenced counter-examples actually isn’t an effective argument at all. Here it is: some who argue that semicolons should always be used will trot out an example like this:

If you call this function, do you know what will be returned? Not ‘boo!’, but undefined!

oh-no-hindenburg

So why does the function return undefined and what does that have to do with semicolons? Due to the rules of ASI (described succinctly in this SO answer), and because the return statement does not require an expression, the return statement is considered complete when the line ends. In other words, ASI turns the above function into this:

Now take a look at that and tell me: how can rigid insistence upon the use of semicolons help with this example? It can’t! No amount of semicolons will make this function return ‘boo!’. So we can throw this argument out.

The one thing you do need to be wary of is any line that begins with parentheses or brackets–they might be considered to be part of the previous line instead. So if you write code like this:

ASI will cause that code to be interpreted like so:

In other words, attempt to invoke or perform array access. So, the one caveat when writing semicolon-free code is: either don’t write code where lines start with a left paren or bracket, or use a semicolon in this rare case.

With that said, once I digested these rules for myself, I thought I would try an experiment and write some semicolon-free JavaScript myself for a while to see how it felt and if it caused me any trouble. I’m here to report that several months later, I have yet to suffer any problems from writing semicolon-free code and I’ve never yet personally even needed to start a line with a paren or bracket. The most surprising thing for me was how comfortable and ergonomic it is just to omit that one little character. Objectively, it isn’t a big change, yet somehow it feels like a real luxury to me. I have enjoyed the experience and it actually grates a little bit now when I write code in a project that does use semicolons (because I do believe in following prevailing coding conventions, after all). You also get a few fringe benefits from the semicolon-free style when it comes time to append to the end of lines (think promise chains) and even just when reordering lines of code or reviewing Git diffs.

Overall, the experience of writing semicolon-free JavaScript has been a positive one, to a surprising degree. I would unabashedly encourage you to give it a try for yourself. You may find that you are surprised at how much you enjoy it, too!

The following two tabs change content below.
  • analognico

    One month ago I switched to semicolon-free JS as well. Unfortunately, I frequently ran into the issue having lines beginning with parenthesis: IIFEs!

    (function () { ‘I ❤️ IIFEs’ })()

    Since this is the only case where I had issues until now and you say you don’t have other issues either I just decided to continue writing semicolon-free JS. Great article Adam!

    • Adam Anderson

      You may find it interesting to learn that NPM’s coding style is also semicolon-free.

  • Ray Morris

    Leaving out semi-colons pretty much ruins any chance of ever doing any reliable static analysis, however, and therefore any ability to verify and therefore have any professional confidence of code quality. If you care about code quality, if you want to be able to use even the most basic tools like JSLint, you need to terminate your statements, not have the parser guess what you might have meant.

    It’s been said “If Houses were built like software … then the first woodpecker to come along would destroy civilization.” This is a great example of the type of lazy, sloppy approach that wouldn’t be tolerated in any other engineering field.

    • Adam Anderson

      Ray, your judgemental opinions are embarrassingly ignorant. Let me educate you. You claim that static analysis of JavaScript is impossible without semicolons and reference JSLint, the oldest and least relevant of all JS linters, to support your claim. JSLint is not configurable and will report warnings on semicolon-free code, but that won’t prevent it from performing its static analysis. Moreover, there are several newer JavaScript static analyzers out there that are configurable, including in roughly chronological order: JSHint, TypeScript, Flow, and ESLint. All of these analyzers are able to do their job with or without semicolons, and can be configured not to report the lack of semicolons as a warning. So no, semicolons are not required for static analysis, period. That means that neither the analyzers nor the parsers are guessing a single thing, either. I trust you are appropriately chastised.

    • rickoshay

      Nonsense.

  • rickoshay

    The debate is in the minds of the throngs of developers hopelessly habituated to using semi-colons. I get that but it doesn’t make the use of semi-colons any less irrational. Ditch them, you’ll be glad you did.