117

It seems to be fashionable recently to omit semicolons from Javascript. There was a blog post a few years ago emphasising that in Javascript, semicolons are optional and the gist of the post seemed to be that you shouldn't bother with them because they're unnecessary. The post, widely cited, doesn't give any compelling reasons not to use them, just that leaving them out has few side-effects.

Even GitHub has jumped on the no-semicolon bandwagon, requiring their omission in any internally-developed code, and a recent commit to the zepto.js project by its maintainer has removed all semicolons from the codebase. His chief justifications were:

  • it's a matter of preference for his team;
  • less typing

Are there other good reasons to leave them out?

Frankly I can see no reason to omit them, and certainly no reason to go back over code to erase them. It also goes against (years of) recommended practice, which I don't really buy the "cargo cult" argument for. So, why all the recent semicolon-hate? Is there a shortage looming? Or is this just the latest Javascript fad?

12
  • 2
    "years of recommended practice" refer a question of blacklisted SO polls tag which unlikely makes it authoritative to support any kind of opinion
    – gnat
    Mar 29, 2012 at 12:42
  • 29
    @gnat just because people hate the question being on SO doesn't make it a less valid source of people's opinion.
    – Ryathal
    Mar 29, 2012 at 12:58
  • 4
    @gnat Questions that are "officially considered inappopriate on StackOverflow" are sometimes considered very authoritative by the expert community. Sad but true.
    – MarkJ
    Apr 4, 2012 at 17:15
  • 7
    @gnat The blacklisted question actually has some very interesting examples of why omitting the ; can break your code. So I'd say it's a useful reference for this question.
    – Andres F.
    May 13, 2013 at 12:22
  • 5
    @RickO'Shea overwhelmed by common sloppiness. The reason why I use semicolons is that it is ridiculously easy, it makes line breaks irrelevant at runtime, and allows me not to have to worry about there being "edge cases", about which ones they are, in which JavaScript versions, this kind of things. So you are wrong about my reason for using semicolons. And your point would also apply to using variable names like a instead of meaningful names, which are also "unnecessary" in the sense in which you are using the word. "Unnecessary" is NOT a reason not do do something. Jan 12, 2018 at 16:59

13 Answers 13

91

I suppose my reason is the lamest: I program in too many different languages at the same time (Java, Javascript, PHP) - that require ';' so rather than train my fingers and eyes that the ';' is not needed for javascript, I just always add the ';'

The other reason is documentation: by adding the ';' I am explicitly stating to myself where I expect the statement to end. Then again I use { } all the time too.

The whole byte count argument I find irritating and pointless:

  1. for common libraries like jquery: use the google CDN and the library will probably be in the browser cache already

  2. version your own libraries and set them to be cached forever.

  3. gzip and minimize if really, really necessary.

But really how many sites have as their biggest speed bottleneck the download speed of their javascript? If you work for a top 100 site like twitter, google, yahoo, etc. maybe. The rest of us should just worry about the code quality not semicolon religious wars.

6
  • 4
    I guess the opposite could be true as well. As python becomes more popular for web it's easier to have your JS resemble python.
    – Ben DeMott
    Mar 31, 2012 at 8:37
  • 10
    Try but then the same byte warriors would be after me for unnecessary whitespace at the beginning of lines. ( I would also have Javascript bugs because I would rely on Python's indent rule rather than using { }
    – Pat
    Apr 1, 2012 at 11:21
  • 16
    If reducing byte count is important, you'll have something that minimizes the files as much as possible. If it isn't worth using a minimizer yet, then it isn't worth worrying about removing ';' to save on byte count. Apr 16, 2015 at 20:07
  • 4
    byte count isn't actually necessarily reduced, in-fact it can actually be increased as a new-line is often (not always) actually two characters (new-line followed by carriage-return) so in its most space efficient form the new line will be once character same as a one character semi-colon (if you compact all your JS code in one line which is often done for the deployed JS code, not the development source code).
    – ALXGTV
    May 30, 2015 at 17:46
  • 1
    I like the semicolon at the end, because it since ages that way. Also I can clearly see that is the end of an instruction. Also I believe the tokenizer has less to do. Dec 17, 2019 at 9:19
54

It makes method chaining easier and commit diffs cleaner

So let's say I'm jQuerying about and I have

$('some fancy selector')
  .addClass()
  .attr();

If I want to add stuff and keep my line-based commit diff small, I have to add it above attr. So it's one thought longer than just "add at the end". And who wants to think? =)

$('some fancy selector')
  .addClass()
  // new method calls must go here
  .attr();

But, when I drop the semi-colons, I can just append and call it a day

  $('some fancy selector')
    .addClass()
    .attr()
+   .animate()
+   .click()

Also, if I decide to pop off the last method, I don't have to reassign the semi-colon and pollute my commit again.

  $('some fancy selector')
    .addClass()
    .attr()
    .animate()
-   .click()

Versus the uggo

  $('some fancy selector')
    .addClass()
    .attr()
+   .animate();
-   .animate()
-   .click();
9
  • 56
    This is niche use case IMO. Mar 29, 2012 at 22:30
  • 17
    But interesting nevertheless.
    – Jonathan
    Mar 30, 2012 at 11:30
  • 12
    You can have semicolon at the end on a new line indented as the starting line. Then you copy and reorder things as you wish. This also closes the chain nicely.
    – Nux
    May 11, 2013 at 17:38
  • 24
    Is it just me who wonders why anyone would care how neat the diffs of their commits look? as a general rule, people read code, not diffs.
    – Jules
    Dec 3, 2014 at 12:06
  • 19
    @Jules, cleaner diffs mean merges are more likely to succeed. Feb 14, 2016 at 6:09
30

semi colons in JavaScript are optional

My personal reason for not using semi colons is OCD.

When I use semi colons I forget 2% of them and have to constantly check / add them back in.

When I don't use semi colons I never accidentally put one in so I never have to check / remove them.

4
  • 3
    Good one. I've been burned by a semicolon-less line or two in an otherwise properly semicoloned file.
    – Jonathan
    Mar 29, 2012 at 12:59
  • 4
    There are parsers (e.g. GeSHi) that will not parse your code correctly if semicolons are not present. You could say that humans will not make such mistakes... But seriously - event if all of your team will manage to remember where semicolons absolutely need to be put, do you really think they will remember it without morning coffee? And they will code in many states of minds. Be sure of it.
    – Nux
    May 11, 2013 at 17:08
  • 8
    if that's your problem, you can use a linter to check your code. Nov 22, 2019 at 9:49
  • And your editor likely can find unnecessary semicolons easily, but it cant find missing semicolons.
    – gnasher729
    May 11, 2021 at 13:18
29

There’s no such thing as information overload, only bad design.

— Edward Tufte

It's a general rule in graphic design to leave out unnecessary elements and ornamentation to reduce noise.

Fewer visual elements on the screen means less work for our brains to parse the actual useful information.

let foo = 1

vs.

let /* variable */ foo = 1; // EOL

An exaggerated example of course, but it illustrates the general principle: Additional visual elements should be added if and only if they serve a purpose. So, do semicolons serve a purpose?

The historical reasons to use semicolons in JavaScript were:

  • Maintain similarity to C / Java
  • Avoid compatibility issues with poorly written browsers and tools
  • Helping humans and machines detect code errors
  • Automatic Semicolon Insertion carries a performance penalty

The compatibility issues are pretty much a non-issue today. Modern linters can detect any code errors just as well without semicolons. Similarity with C/Java/PHP can still be a consideration (see the accepted answer by Pat), but just because other languages contain superfluous syntax elements does not mean we should keep them in JavaScript, especially since many other languages (Coffeescript, Python, Ruby, Scala, Lua) do not require them.

I did a quick test to see if there was a performance penalty in V8. This is Io.js parsing a 41 MB JavaScript file (Lodash repeated 100 times) with semicolons and then with semicolons removed:

$ time node lodashx100.js
node lodashx100.js  2.34s user 1.30s system 99% cpu 3.664 total
$ time node lodashx100s.js
node lodashx100s.js  2.34s user 1.15s system 99% cpu 3.521 total

Everyone has to decide their own preferred coding style for their projects, but I no longer see any tangible benefit in using semicolons, so to reduce visual noise, I've stopped.

4
  • 5
    I would counter this argument of leaving out unnecessary elements in the load the mind has to now do to add back in optional syntax. Now the semicolon is not a huge mental strain if omitted. This is an issue I've experienced with Ruby and Scala. When it becomes a chain of calls with calls inside of calls, and they've all omitted every paren, it is a burden to pull apart.
    – Seamus
    Oct 2, 2016 at 16:43
  • 1
    beautiful answer 👏
    – Alex Cory
    May 22, 2020 at 20:49
  • As your comment so nicely shows, we could omit ; and {} from most languages like python does because they are mostly a fetish. Unfortunately, most "rational" programmers like their fetishes. May 10, 2021 at 18:05
  • 2
    I agree less visual clutter is better, but adding 20 unnecessary distracting characters to prove that a single character is distracting doesn't seem like a fair example.
    – kapex
    May 11, 2021 at 11:50
23

I recently wrote a parser/analyzer for JavaScript, where I had to painstakingly implement ASI, and I also have my copy of Crockford's JavaScript: The Good Parts on my bookshelf, which advocates always using semicolons. The intention was good, but it doesn't always help in practice.

Obviously, the people writing frameworks like jQuery, zepto, etc. are JavaScript syntax masters and thus they know the difference between:

return
{
    status: true
};

and

return {
    status: true
};

JavaScript, while powerful, is also a beginner's language and good luck explaining this to someone who is just learning what a for loop is. Like introducing most people to a new skill, there are some more complex things you don't want to explain right away, so instead you choose to instill a "cargo cult" belief in certain things just to get them off the ground. So, you have two choices when teaching a beginner how to write JavaScript:

  1. Tell them "follow this one rule and don't ask why", telling them to put a always semicolon at the end of every line. Unfortunately, this doesn't help in the example in the above, or any other example where ASI gets in the way. And Mr. or Ms. beginner programmer gets befuddled when the code above fails.
  2. Tell them "follow these two rules and don't ask why", telling them not to bother with semicolons at the end of every line, and to instead always a) Follow return with a {, and b) When a line starts with a (, prepend it with a ;.

Choosing option 2 is a better set of "cargo cult" rules to follow (will result in very few ASI-related bugs), and even if you do get a deep understanding of the topic, you have fewer unneeded characters on the screen.

12
  • 10
    All right, I'll bite. Help me understand the difference in syntax between the two examples above. My untrained eye only sees a difference in formatting. Mar 29, 2012 at 20:27
  • 10
    Or, on the other hand, I stumbled across the answer by sheer accident. In the first example, the return is considered a solitary statement and the line-end is the equivalent of a semicolon. The second example actually returns the object. Tricksy. Mar 29, 2012 at 20:30
  • 10
    I don't think I can agree with the idea that JavaScript is a beginners language, there are tons of inconsistencies and surprise effects in JavaScript that don't have simple explanations. IMO a beginners language wouldn't be like that, I would call JavaScript an intermediate language.
    – Ryathal
    Mar 29, 2012 at 20:32
  • 16
    Clarifying point: the return example is actually an exception to the normal JS behavior which is to attempt to pull lines together when a semi-colon is omitted. return, break, and continue all exhibit this exceptional behavior in which a trailing newline is always interpreted as an end of statement. (Source is Flanagan's "JavaScript: The Definitive Guide" pp25-26). Personally, I strive for the idea of "code of least surprise." Leaving semi-colons out tends to result in more surprises than anything (I generally also keep my curly braces even for simple statements).
    – Kyle
    May 13, 2013 at 16:58
  • 3
    When the line starts with [, it needs a semicolon too. Dec 3, 2014 at 8:11
9

Choosing a programming convention is effectively the same as choosing subset of the target language. We all do this for the usual reasons: code readability, maintainability, stability, portability, etc. -- while potentially sacrificing flexibility. These reasons are real business reasons.

Reasons such as "saving keystrokes," and "programmers should learn the JavaScript rules" are marginal business reasons so they carry little practical weight.

In my case I needed to come up to speed in JavaScript very fast, so leveraging a limited subset of the language was to my advantage. So I chose the JSLint subset of JavaScript, turned on the Rockstar apps JSLinter in Eclipse to the most restrictive settings I could stand, and haven't looked back.

I'm grateful to be able to avoid the details of the difference between "==" and "===", or the details of semicolon insertion, because I've got a mile high task list already and those details won't help get those jobs done one second earlier.

Of course the most important thing about a convention is consistency, and thinking of it as a language subset helps to reinforce this imperative. And although this may not help answer the OP's question, I think it might help with the practical framing of it.

9

Quite an old question, however I'm surprised no one has mentioned:

Minification: If you happen to minify a JavaScript snippet that doesn't explicitly end the statements with a semi-colon character, you might end up having a hard time trying to figure out what is wrong with a snippet that was just working before the minification and now doesn't work.

Ambiguity: Semi-colons are optional, true, however by eliminating them from the source-code, you might leave some ambiguous scenarios to the parser to decide on its own. If you are writing a 100 lines of code for an online shop, yes, maybe it doesn't matter, but more serious tasks would require a 100% clarity.

Long time ago I read a very nice analogy about something else but it's very true in this case also: (In our case) Eliminating the semi-colons is like crossing at a red light. You might be okay in the end or you might get hit by a truck.

Why it's becoming more popular these days?

I personally believe having JavaScript runs on the server-side had a lot of effects on the JavaScript community itself. In our case, obviously no one is going to minify the JavaScript on the server-side (as the source-code is not supposed to ship to the client's web browser), so having no semi-colons looks much safer which is true; however the other developers who learn from these books, articles and videos, they unfortunately dismiss the fact that JavaScript on the server-side is not exactly the same as JavaScript in the client-side.

2
  • Minifiers could leave in single-character newlines or insert semi-colons when semi-colons aren't present without a size penalty. I don't know which (if any) minifiers do this. The danger still exists in at least some of them, so your point still holds in practice.
    – outis
    Jul 12, 2015 at 23:25
  • 9
    If a minifier breaks your code then the minifier is broken and you should not use it.
    – Jbm
    May 8, 2020 at 17:20
8

There are good reasons to keep them in.

They are not really optional, JS can add them back in with automatic semicolon insertion when they are missing but that is not the same thing.

Douglas Crockford's JavaScript: The Good Parts says on two separate occasions that it is a bad idea. The automatic semicolon insertion can hide bugs in your program and creates ambiguity.

JSLint doesn't approve.

8

For a long time this was basically a question of personal preference. But with recent developments of JavaScript syntax, omitting semicolons becomes a lot more problematic.

With Ecmascript 6, we get destructuring assignments which makes it normal to start a line with a square bracket, e.g.:

[a, b] = [b, a]; // swap a and b

But this line will give weird errors if the previous statement is not semicolon-terminated, e.g.:

foo()
[a, b] = [b, a]; // <-- weird error

Because this is actually parsed as:

foo()[a, b] = [b, a];

Which is legal syntax but certainly breaks the Principle of Least Astonishment.

A semicolon solves this ambiguity.

4
  • Solves this ambiguity? There is none according to language-rules. Changes the result of parsing? Sure, and often even to what is desired. May 25, 2021 at 11:30
  • 4
    @Deduplicator: It is ambiguous to a reader, since it is not clear if this is supposed to be a weirdly formatted single expression or if it is a bug. Using semicolons solve this ambiguity and makes the intention clear. Of course the parser will parse it according to the spec, but the purpose of code formatting is to communicate to the human reader.
    – JacquesB
    May 25, 2021 at 12:07
  • An important point that gets mentioned too seldom. However, provided sufficient tooling (ESLint, maybe TypeScript), it still can be dealt with. In these cases you will have to use the semicolon. Prettier with no-semi will put the semicolon at the beginning of the line then, i.e. ;[a, b] = [b, a];, which of course introduces inconsistency. Aug 15 at 15:17
  • Nice example of what happens when omitting semicolons. It works 99.99% of the time, but eventually you shoot yourself in the foot. Another example is if you use constructs like this: ['A', 'B'].forEach(item => { /* ... */ }) Sep 22 at 13:34
2

I have two theories:

A)

The thing about this choice is that back in the day, when JSLint etc. were applicable, you were choosing to spend a large amount of time catching obscure syntax errors, or a reasonable amount of time enforcing a standards policy on code.

However, as we move more towards Unit Test-driven code and continuous integration the amount of time (and human interaction) required to catch a syntax error has decreased massively. Feedback from tests will quickly indicate if your code is working as expected, well before it gets near an end-user, so why waste time adding optional verbosity?

B)

Lazy programmers will do anything to make their own lives easier in the short term. Less typing -> less effort -> easier. (also, not having to semicolon will avoid straining your right-hand ring-finger, avoiding some RSIness).

(N.B. I disagree with the idea of omitting something that disambiguates a statement).

4
  • 1
    jshint is still an important tool.
    – Raynos
    Mar 29, 2012 at 16:40
  • As for disambiguating a statement, both \n and ;\n are the same
    – Raynos
    Mar 29, 2012 at 16:41
  • 2
    @Raynos Actually, I've found that JSLint tends to be a bit useless with the complexity of some of the framework-heavy code I often work with. Plus, ;\n and \n aren't the same in all circumstances, otherwise there'd never be a need for the ;.
    – Ed James
    Mar 29, 2012 at 16:48
  • 7
    jslint is useless, jshint however is a different tool.
    – Raynos
    Mar 29, 2012 at 17:09
2

JavaScript hasn't needed semi-colons to terminate statements in over a decade. That's because newline characters are considered statement terminators(I believe this is also mentioned in early ECMAScript specs). It really makes a lot of sense, especially since there really is no good reason [that I know of] why JavaScript would need frequent use of semi-colons but not other interpreted declarative languages like Ruby or Python.

Requiring semi-colons may make it easier to write a parser for a language, but if every interpreter out there supports the omission of semi-colons then what exactly is the point?

What it comes down to is how knowledgeable a programmer is: if you know that you can omit a semi-colon, feel free to do so understanding that there may or may not be a consequence. Human beings are decision-making machines and nearly all decisions require some compromise or trade-off. The trade-off to just throwing semi-colons all around your code(even in places where they aren't needed) is that your code becomes less read-able(depending on who you ask) and JSLint won't complain(who cares). On the other hand, the trade-off to omitting semi-colons is the fact that 90% of JavaScript programmers will chastise you for it, but you may end up enjoying writing JavaScript more because of it.

What sounds better to you; making informed decisions or blind decision-making / herd-mentality?

3
  • I'd be interested to know why this has received downvotes. JavaScript doesn't need semi-colons to terminate statements; it can certainly use them, but they are by no means a requirement. If they were needed, then nobody else's explanations would work. The fact(yes, a fact) that you can write an entire JavaScript application with few to no semicolons demonstrates this. Beyond that, I don't see how understanding how a tool works and using one's own reasoning to make decisions is somehow objectionable in contrast to "just do it". That's what's known as religion. Aug 27, 2015 at 23:28
  • 7
    I didn't downvote, but the issue might be that this is factually not correct as written. Newlines are not considered statement terminators in javascript. You can leave off semicolons because of a feature called automatic semicolon insertion which allows it to fix parse errors automatically in certain circumstances. The people who advocate semicolons argue that many javascript programmers seem to poorly understand this rule. Your post seems to be an argument in their favor in that light. (In fairness, I mostly agree with your thesis, but for different reasons) Apr 26, 2018 at 21:13
  • 1
    @TimSeguine Yeah, I wrote this back before I had a better understanding. I still don't think it's objectively wrong to not use semicolons so long as the people doing so understand what exactly it is that they're doing. I should rework my post, or perhaps get rid of it since enough others have chimed in about this. Thanks for the polite criticism! :) Apr 26, 2018 at 23:21
1

I don’t leave them out, but i change the rules when to insert them.

The rules most people use is

  • Before each line ending
  • Except the line ends with a } coming from a function statement
  • But only a function statement, not assignment to a function literal

My rule is: At the beginning of every single line starting with a opening brace/bracket.

Mine is simpler, therefore easier to follow and less prone from bugs. Also the low number of semicolons makes it easy to find bugs made by leaving it out.


Another argument is that the infamous return\nvalue bug comes from not knowing about ASI. My rule forces you to know about ASI, so people using my rule are less likely to fall into the trap of that bug.

4
  • I know this sounds cliché, but "why did I have to scroll so far to find the best answer?" I am always dumbstruck when I see return\n as an argument FOR semicolons. And in my experience, most of the times I see a line starting with a brace, it's because someone's trying to be fancy rather than readable — with the exception of self-executing anonymous functions. Apr 22, 2021 at 21:55
  • 1
    Haha if I wrote that again today, then less smugly but with the same reasoning: Hiding en existing language rule is worse than making it apparent. And I completely agree about the “trying to be fancy”. Apr 23, 2021 at 9:49
  • Glad to hear from you! I happen to code alone, so no semicolons for me — and no fanciness either. Apr 24, 2021 at 3:33
  • @flyingsheep: How about if a line start with a regular expression? Or a template string?
    – JacquesB
    May 25, 2021 at 11:14
1

Here's a pros and cons list. This answer is marked as "community wiki", so feel free to edit it and add more pros and cons. Realize that you might not agree with all of the pros/cons on these lists - I certainly don't, but they're still there to represent the points of view out there. Also remember, a longer pros list does not automatically make it better.

The term ASI will be used frequently, and means "Automatic Semicolon Insertion" - this is the (broken) algorithm Javascript uses to decide where semicolons belong when they're omitted.

Pros of using semicolons

  • It is easier to remember to add a ";" at the end of each line, then to remember the rules of omitting semicolons. (However, see the final point at the end about why it's still worthwhile to know how ASI works)

  • When coding without a linter (or with a not-so-good linter), you're a lot less likely to bump into ASI issues.

  • It creates less friction when teammates often switch between other languages that require semicolons, such as C++ or Java.

  • It makes code intention very clear and unambiguous.

  • This has already been the long-standing "standard", many online code snippets are written with semicolons, which makes for easy copying-pasting. Why segment the community?

  • There is no guarantee that the "safety rules of omitting semicolons" will stay stable. For example, it's been argued that there's a handful of places where ASI hazards could come into play, but only a couple of them matter for any non-contrived piece of code, and those can be avoided by putting a semicolon before a [ or (. However, the introduction of the upcoming pipeline operator will bring a number of new places where we have to watch out for ASI hazards (like, const value = 2 \n -3 |> f(%) will be treated as one statement, not two).

Pros of omitting semicolons (and instead adding them before [ and ( at the beginning of lines)

  • It creates less friction when teammates often switch between other languages that don't require semicolons, such as Python. (It can be annoying to often go back and insert forgotten semicolons).

  • Semicolons can feel like extra visual clutter

  • Smaller diffs (to help avoid merge conflicts). e.g. changing

    array
    .filter(...);
    

    to

    array
    .filter(...)
    .map(...);
    

    causes two lines to be changed instead of one.

  • If you're often starting lines with [ and (, then you're probably doing more advance techniques, and it might be worthwhile to dumb down your code anyways. e.g. use a normal for loop instead of ;[1, 2, 3].forEach(...).

  • If you're not using a minifier, it makes for a slightly smaller byte count. Automatic gzip-compression mitigates this issue if enabled on the server.

  • It's still possible to bump into ASI issues when coding with semi-colons (although it's much less common). A commonly cited example is the following (incorrect) attempt at returning an object. This code instead returns nothing, because a semi-colon will automatically be placed between return and {.

    return
    {
      x: 2
    };
    
  • Less keystrokes


The answer to the original question (Why the recent shift to semicolon-less code?) is that it really comes down to personal/team preference. It's not until recently (because of the popularization of the safety rules of semicolon omission) that those who don't like semicolons can feel free to actually omit them in a professional setting. This has caused a major shift with many groups of people choosing to leave semicolons out. This is all done because of personal, team, or company preference, not because it's objectively better (though some may argue otherwise). In other words, it's not that the entire community is changing its opinions to now prefer semicolons, rather, the community members who already prefer to code without semicolons now have the means to do so.

As a final point, I want to make an important point clear. Semicolons are not a substitute for linters. Once a good linter is in place, you'll never run into ASI issues, no matter if you choose to use semicolons or not. But many people do not use linters 100% of the time (which is reasonable). Without a linter, you're going to run into ASI issues no matter which route you choose. Yes, even semicolon users will bump against ASI - such an issue was recently stumping a friend of mine (it's easy to forget a semicolon after doing const fn = function() { ... }). For reasons such as this, it can still be worthwhile to learn how ASI works, even if you choose to put semicolons everywhere.

You'll find that many of the pros/cons listed above vanish when good tooling is used and many others are very subjective, which is why it really just comes down to people's preferences.

Not the answer you're looking for? Browse other questions tagged or ask your own question.