Seven Things You Should Stop Doing with Node.js

Seven Things You Should Stop Doing with Node.js

Inspired by 5 Things You Should Stop Doing With jQuery by Burke Holland, I decided to open a discussion and highlight seven things you should immediately stop doing with Node.js:

  1. Stop using callbacks
  2. Stop using * for versions
  3. Stop using console.log for debugging
  4. Stop using GET and POST for everything
  5. Stop using semicolons
  6. Stop using comma-first style
  7. Stop limiting your connections with default maxSockets value

Stop Using Callbacks in Node.js

Callbacks are the bread and butter (or the meat and veggies for paleo lifestyle readers) of the JavaScript/Node.js language and the main pattern. However, you should stop using callbacks for nesting code of multiple methods unless you want to end up with the Callback Hell.

Async is for the win. Particularly its series() and waterfall() methods.

To illustrate the drastic difference, here is an example in which we perform multiple operations with callbacks to find a user, then find posts that belong to the user:

codeA(function(a){
  codeB(function(b){
    codeC(function(c){
      codeD(function(d){
        // Final callback code        
      })
    })
  })
})

The series example:

async.series([
  function(callback){
    // code a
    callback(null, 'a')
  },
  function(callback){
    // code b
    callback(null, 'b')
  },
  function(callback){
    // code c
    callback(null, 'c')
  },
  function(callback){
    // code d
    callback(null, 'd')
  }],
  // optional callback
  function(err, results){
    // results is ['a', 'b', 'c', 'd']
    // final callback code
  }
)

The waterfall example:

async.waterfall([
  function(callback){
    // code a
    callback(null, 'a', 'b')
  },
  function(arg1, arg2, callback){
    // arg1 is equals 'a' and arg2 is 'b'
    // Code c
    callback(null, 'c')
  },
  function(arg1, callback){      
    // arg1 is 'c'
    // code d
    callback(null, 'd');
  }], function (err, result) {
   // result is 'd'    
  }
)

Stop Using WildCard * for Versions with Node.js

The wildcard * instead of the version number in package.json seems like a good idea — an automatic update in the near future. Wrong! You should use exact version numbers to prevent any third-party module changes from breaking your app and waking up you in the middle of the night wondering what went south.

This is especially true if you don’t commit your node_modules folder or don’t use shrinkwrap.

A bad example from HackHall package.json circa summer 2013:

{
    "name": "hackhall",
    "version": "0.0.1",
    "private": true,
    "main": "server",
    "scripts": {
        "start": "node server"
    },
    "dependencies": {
        "express": ">=2.2.0",
        "jade": "*",
        "mongodb": "*",
        "mongoose":"",
        "oauth":"*"
    },
    "devDependencies":{
        "mocha": "",
        "superagent":""
    },
    "engines": {
      "node": ">=0.6"
    }
}

A good example from the Practical Node.js book [2014, Apress]:

{
  "name": "blog-express",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app.js",
    "test": "mocha test"
  },
  "dependencies": {
    "express": "3.4.5",
    "jade": "0.35.0",
    "mongoskin": "~0.6.1",
    "stylus": "~0.40.3",
    "mocha": "1.16.2",
    "superagent": "0.15.7",
    "expect.js": "0.2.0"
  }
}

If you don’t want to go to NPM website every time to check the version, you can use $ npm install package_name --save which will save the version number in the package.json.

If the module is installed already you can:

  • Type $ npm ls
  • Open the package folder and copy the version number form package.json

Stop Using console.log for Debugging Node.js Apps

What is the best debugger? Right, it’s console.log! It’s fast, non-interrupting and gives us any information we ask for (like the value of a pesky variable). Then why should you stop using it? Because real debuggers like Node Inspector provide not only the value of a variable you just hard-coded, but also give you a dynamic ability to look around, inside the process.

For example, I might have a condition (where resubmit is a boolean) that is not acting right:

if (resubmit && post.published && user.plan.paid && post.isVisible) {
  // code A
} else {
 // code B
}

With console.log I can type only console.log(resubmit), or console.log(resubmit, ...) some other variables. But, with debugger, I can poke around and print anything I have access to in that scope. If that is not enough, I’ll step over or step in the Code A or B as show in the example.

Stop Using GET and POST for Everything in Node.js servers

Stop using GET and POST for all of your incoming HTTP requests. Representational state transfer application programming interface methodology (RESTful API) has PUT and DELETE so use them for updates and deletions (wiki).

For example in this Express.js route, instead of using POST to update a record, you can use PUT:

app.post('/comments/update/:id', routes.comments.update)
app.put('/comments/:id', routes.comments.update)

For more information, take a look at REST API Tutorial.

Stop Using Semicolons with Node.js

Semicolons are actually optional, because ECMAScript (the standard for Node.js and browser JavaScript implementations) has an automatic semicolon-insertion feature (ASI). Here’s the draft of the ECMAScript 6 (ES6) documentation about ASI.

The gist is that semicolons are optional and except for two cases: in front of the IIFE and inside of the for loop.

The problem with using semicolons:

  • Extra characters to type: In a 1,000-line file there will be at least 1,000 extra symbols
  • Inconsistency: When semicolons are missed due to neglect, the code base still works but becomes inconsistent (solvable by linting, but that’s an extra build step)

Some popular Node.js projects have been written with a semicolon-less style:

  • NPM: the Node.js package manager
  • Request: a module for making HTTP requests

Are you still doubtful because Doug Crockford told you that you had to use semicolons? Then maybe you should read An Open Letter to JavaScript Leaders Regarding Semicolons.

Stop Using Comma-First Style

Okay, this topic is very subjective and probably not that important, but I want to voice my dislike for the comma-first style. Please, stop the madness!

The style in question is often seen when one might write arrays and objects with a comma at the beginning of lines instead of at the end. For example, we can define an array:

var arr = [ 'nodejs'
  , 'python'
  , 'ruby'
  , 'php'
  , 'java'
]

Or in a more traditional style it would look like this:

var arr = [ 'nodejs', 
  'python', 
  'ruby', 
  'php',
  'java'
]

Please, don’t do the former. I don’t care how much better it might be for catching missing commas. The comma-first style just look ridiculous, because we would never use this style in our normal language writing. Nobody writes like this:

Paleo lifestyle is good for ,adult men ,adult women ,children ,and elderly people.

In my humble opinion, comma-first style is hard for the brain to adapt and just plain silly.

Stop Limiting Your Connections with Default MaxSockets Value

The default maxSockets value is 5 and it determines the limit on number of sockets per host (official docs).

To avoid bottlenecking your system just use something like this:

var http = require('http')
http.globalAgent.maxSockets = 10

Or, if you want to make it unlimited:

require('http').globalAgent.maxSockets = Infinity

Here is a good comparison article Node.js Connection Pooling.

Another approach is to disable pooling all together (agent: false) like LinkedIn did or Substack recommends in his hyperquest module.

Conclusion About Things to Stop Doing with Node.js

Of course, this list of seven things you should immediately stop doing with Node.js is subjective, but it was born out of careful and ongoing observation, as well as some painful real-world experience (i.e., * in package.json). What is on your list of things not to do with Node.js?

Author: Azat

Techies, entrepreneur, 20+ years in tech/IT/software/web development expert: NodeJS, JavaScript, MongoDB, Ruby on Rails, PHP, SQL, HTML, CSS. 500 Startups (batch Fall 2011) alumnus. http://azat.co http://github.com/azat-co

78 thoughts on “Seven Things You Should Stop Doing with Node.js”

  1. I always look both ways when I cross the road, regardless if its a one way street or not. It’s just easier to remember and I know I won’t get myself in to trouble by thinking the road is one way when its not. Likewise, I always use semicolons. Its actually a convention of the language and to be honest, if you want to collaborate with other JS programmers then the chances are they will be semi-colonicers – so you don’t have to waste time convincing them to stop colonicing.

  2. Thank you so much for saving us from the harm of non-optimal semi colon use, and instructing me how to write code that’s easier for people who don’t like leading commas to understand. I mean, in the big world of web programming languages, the last thing us compulsory polyglots need is an ambiguous option for element separation.

    I had been trying to wrap my head around various promise frameworks recently. I assumed that they were tricky to understand because of their asynchronous nature and their oddly ambiguous terminology; but upon reading this game-changing article, I realized it was due to the example code having BOTH semicolons at the end of statements AND leading commas in collection literals!

    This is a glorious day.

  3. Well, maybe Node.js is not designed for large and complex apps, because the philosophy behind NPM tells us to build modular systems. That is have many small services instead of large complex monolithic apps. This small apps approach is more advantageous.

  4. Agree about console.log. Debuggers teach you so much because they show you what you /aren’t/ looking for. Console logging encourages guessing, which encourages disaster.

    Async lib is buggy. The real solution is to use async/await via Tracer until ESA rolls out. Using async/await is the only way to actually avoid callbacks (granted until there are native implementations, transpilers use CBs under the hood).

    I think you forgot one of the most important “stops”: stop using node for large, complex applications. Flow, TS, and AtScript offer hope in this regard, but vanilla ES5 is a terrible choice if you want your code to scale beyond a small team consisting of the original authors.

  5. Spaces for indentation is better, because in different systems/editors/environments 1 tab can be interpreted as 2 or 4 spaces… which might lead to confusion. So stick with 2 spaces and don’t use tabs (EVER)… and you’ll be okay.

  6. Great article.
    I think there is some contradiction between the 5 and 6 points –
    Stop using semicolons
    Stop using comma-first style

    I dislike comma-first style, tho I can understand its benefits I just find it annoying to read.
    I also find it annoying to read code that doesn’t end every statement with a semicolon.
    For a while now I thought to stop using semicolons and hopefully get used to it after a while.
    But after reading Izs open letter you linked to from your post I understand that removing semicolons and comma-first style go hand in hand.
    Izs clearly says that there are some situations you might have to use semicolons, in this situations he prefers to use semicolons first style so it will be more readable, he gives the following example –

    foo()
    ;[1,2,3].forEach(bar)

    So I think for consistency if you use semicolon-first style you should use comma-first style.
    I guess you can decide to only use semicolons in the end of a line where they are necessary but I think the small OCD part of me will snap seeing some lines end with semicolons and some that don’t, it doesn’t feel very consistent.

    The only real issue I find with semicolons (Other than people not using them) is that they take a bit more space, On the server side of things this is negligible and on the client side this is solved with minification.

    So personally I will stay with semicolons and comma-last style.

    Other than that I would add another annoying point of using spaces for indentation.
    I can’t understand why people use spaces instead of tabs for indentation but they should stop.
    Its annoying, inflexible, and if were talking about unnecessary chars it much more worse than semicolons.

  7. sir i do not agree with your views on comma first approach, comma first approach is convenient and less buggy than traditional style. I myself used to detest it early on but commas create innumerable bugs

  8. Regarding comma first… you wouldn’t write html like this…

    <li>
    list item</li><li>
    another item</li><li>
    ...</li>

    The comma lets you see it upfront… it makes an even bigger difference when your lines are longer. There’s also less likely to be a mistake when you comment out a line.

  9. That’s right, stop using nested callbacks (hell) in the particular case that I showed where async can be used.

    I almost never use node inspector myself. I just wanted to point out that console.log is not the only option.

  10. i’m aware a semi-colon in a javascript code line is useless and avoidable.. but i still use it because it gives me an edge, an end point for a statement. and since is harmless i’ll keep it.

  11. – Stop using callbacks

    More like, use callbacks properly to avoid callback hell. Your examples alone use callbacks.

    – Stop using console.log for debugging

    Using node-inspector on simple things would be overkill when a simple console.log would have done fine.

    You should stop using “stop using”. But hey, I learned a few from your blog post, so thanks!

    Happy new year!

  12. I’ll preface this by saying I’ve been coding for Node since 2009, and doing it in production with millions of monthly users almost daily for the better part of the last two years. I’m also the author of “Programming JavaScript Applications” (O’Reilly).

    Stop callbacks? Um… no. First of all, this is not even possible with Node, because the callback style is standardized and if you ever want to use any other Node API, callbacks are required. Second…

    Async – I consider async an anti-pattern. Over reliance on it has caused serious maintainability problems in two large production codebases I have been involved with. To avoid those problems, try going more functional instead. For example, promises + array extras or (if you want to charge full-tilt into the new world), Highland.js or RxJS.

    Semicolons – Until there’s a simple lint solution for ASI-aware semi-colon free styles, this is a really bad idea, but I am totally in favor of eventually going semicolon free. See http://chimera.labs.oreilly.com/books/1234000000262/apa.html#use_semicolons

    If there’s a super-easy semi-colon-free lint option available already, please share it! =)

  13. Async is great for a lot of things (parallel execution of functions, etc etc).

    For sequential stuff and asynchronous flow control I much more prefer promises (like the Q library). It feels more elegant and “proper”.

  14. “That is an heavy endless debate. People should do whatever the f**** they want with semicolons. ” — this would be true if one person’s code would never be intended for reading by other developers, and this is not true. With GitHub, it is is even more untrue. People should not do what they want if they want to collaborate.

    “I find it pretty, again only a matter of tastes.” — who said it’s not? Do you know the meaning of the word “subjective”? I.e., quote from my text: “this topic is very subjective and probably not that important”.

    “LoL, we are in a programming language there, and semicolons could also be an argument to do it “in our normal programming language writing”…” the more programming language work as normal language (i.e., our brains) the better for programmers, this term is called expressiveness. For example, Java is less expressive than JavaScript.

  15. Stop using callbacks
    By using async you are actually using callbacks. So use callbaks but by avoiding the callback hell.
    An alternative solution that could be mentioned are Promises (I personally like bluebird).

    Stop using semicolons
    That is an heavy endless debate. People should do whatever the f**** they want with semicolons. I don’t use them. But you can not say “don’t use semicolons, it’s bad”, it is not.

    Stop using comma-first style
    I find it pretty, again only a matter of tastes.
    > because we would never use this style in our normal language writing.

    LoL, we are in a programming language there, and semicolons could also be an argument to do it “in our normal programming language writing”…

  16. “Also, if you are minifying your code (you should be) then the number of semicolons in an unminified file is irrelevant.” why would someone minify Node.js code? 1,000 lines of code is roughly 1,000 extra “;” to type for a developer.

    “linting/code quality system” – why? If the whole point of linting is to make me go and fix “;” then I’d better not use “;” at all.

    “this list is VERY subjective” – virtually anything people write on the Internet is subjective, get over it.

  17. I hate to jump in on the flame way happening, but your statements about semi-colons don’t make sense.

    “Extra characters to type: In a 1,000-line file there will be at least 1,000 extra symbols”

    Nope. You don’t use a semicolon at the end of every line. You use a semicolon at the end of every statement. I can tell you haven’t used semicolons in a while. Also, if you are minifying your code (you should be) then the number of semicolons in an unminified file is irrelevant.

    “Inconsistency: When semicolons are missed due to neglect, the code base still works but becomes inconsistent (solvable by linting, but that’s an extra build step)”

    I agree with the issue of consistency, but you should have some sort of linting/code quality system in place whether you use semicolons or not, so it becomes irrelevant. It’s also not necessarily a build step if you have the linter built into your editor.

    Yes, this list is VERY subjective. #2 is the only one that I would agree should be a hard and fast rule. #1 and #3 offer good tips but are not absolute. #4 only really matters if your back end is actually set up as a RESTful API rather than a full web server, in which case you are actually likely to see people using PUT and DELETE.

    I don’t like to demean other people’s work, but you really should think a bit harder about what you’re saying before throwing it onto the internet.

  18. You should re-read Isaac’s article on semi-colons where he explains why fixing this example has nothing to do with semi-colons.

  19. My approach is to omit semi-colons and to not lead lists with commas, in other words it’s a hybrid of NPM and non NPM-style.

  20. You still have to remove a comma if you remove the first line, and type the comma if you uncomment the first line, so both way you got the same amount of work/typing.

  21. Hey Genius,
    my rationale for using comma-first is to be able to comment ANY the line without typing that extra comma with each change.

  22. …of course what i ment by ‘weapons’ are Your ‘tools of the trade’.
    Make code not war nor flame. Peace.

  23. Oh my…

    One of the worst post ever i spent my time reading!

    STOP using callbacks? Even in Your own example You name Your callbacks, well, what they are – ‘callbacks’.
    You ment to say ‘avoid them nested’, right?

    STOP using console log? What if i am not real-time debugging, but want a simple output of what is going on? A promise succeeded or failed? My errors are explicit enough? I just print them to the console and i already know what is going on/went wrong…I don’t always need to be wasting my time executing line-by-line all statements and functions.
    I was hoping to read something like, use a logger module like winston…that would have made more sense!

    I’ll STOP here, because the rest of the article is waay too opinionated to discuss it for real, in my humble opinion.

    My point is that the STOP sign was really just the hip thing to say. The whole article could have been less ‘dictatoric’ than it finally is with more ‘recomendations’ than ‘do-this-right-NOW’.

    My five cents to rename the post to ‘know your weapons’. No offense. Stop.

  24. Your argument for the comma first could be used on the semicolons debate as well though. it comma-first does not sit well with the brain, then semicolon less programming is the same problem. I know for a fact some collegues will have an easier life programming with semicolons because it gives the brain a clear point where a statement stops.

    You don’t go writing in plain english removing all the dots after each sentence do you?

    So therefor I would vote for your item 5 and 6 both to be highly subjective, and let developers decide for themselve if they want to code in a certain style or not. (it is up to them to support their own style in their team, with the needed extra workflow steps like linting if they really want to work that way).

  25. Just sayin’, #1 is very misleading. Callbacks are required in JavaScript. Or for any asynchronous style, really. You want people to stop *deeply nesting* callbacks. Which I am in complete agreement on

  26. I use semicolons partly out of habit, but also because I may push some of my code from backend to frontend. I use the combination of JSHint and JS-SRC to ensure consistent code quality.

    I can sort of see the argument for saying “in a 1,000 line file you’ve got 1,000 redundant bytes”. I don’t think it’s really an issue on a server though and probably not even in browser. Secondly, I would ensure that your files are shorter (a limit of 500 lines is a good idea) as it reduces complexity and improves maintainability. Make each file do one thing well.

  27. There is one good thing about comma first: commenting out an arg while debugging. You can comment out an arg while leaving the code in line, without breaking the app.

  28. @Krish, do not worry about it. There is nothing bad in using semicolons. And JSHint can check that you have them in right places. @colin puts it into place, ASI is just an error-correction procedure and imho, it’s stupid to rely on it.

  29. I love how the NPM code example you posted, boasting the lack of semi-colons, also has leading commas. So is that code good or bad, then?

  30. Nobody writes like this:

    Paleo lifestyle is good for ,adult men ,adult women ,children ,and elderly people.

    ^^ no, but neither does anyone think like this:

    Paleo lifestyle is good for adult men and also (wait for it) .. adult women and also .. children and also .. elderly people.

    But they do think like this:

    Paleo lifestyle is good for adult men … oh and also adult women …. oh and also children …. oh and also elderly people.

    Think about the development lifecycle for once. People come back to lists and append. Fussing with an existing line to add a comma is a pain in the butt, for multiple reasons (and editors and SCMs etc).

  31. Oooo .. way to piss off your readers. Stop using semicolons in JS? As with the ‘with’ block, the optional behavior of semicolons has been recognized by much of the community as a huge mistake, because it can lead to unexpected failing behavior. Stop leaving them out! Same with starting a brace on the next line, for the same reason: leads to unexpected failing behavior.

  32. The problem with leaving out semicolons is that it can break your code very subtly:


    return
    {
    x: 42
    }

    That return statement will always return undefined. Leaving yourself open to errors like this just to save a few keystrokes is just plain stupid.

  33. With projects like Browserify gaining ground, i.e. isomorphic code that can run on front and backend JS environments, I think it’s still important to keep semi-colons, for all the reasons that Crockford states.

    If you’re definitely not writing code for the front-end. Hey, don’t bother. You’re not minifying your backend code right?

  34. Which is easier to remember?

    Always use semi-colons

    or

    Don’t use semi-colons except for a couple exceptions you read in a blog post (IIFE and for loops) and hope there aren’t any other exceptions you missed that could take forever to debug.

    Also, just use trailing commas in your arrays. Unless you’re still supporting IE8, it’s even safe to use in the browser, but I’d understand if you still wanted to be careful. But in Node, it’s perfectly safe.

    Oh, and unless you’re using TextEdit, your editor probably has a live-linting tool or plugin (i.e. SublimeLinter for SublimeText) which makes it trivial to lint your code as you go, and you’ll never miss a comma (or 100 other things) ever again.

  35. Funny you cite Isaac Schlueter’s “An Open Letter to JavaScript Leaders Regarding Semicolons” in which he writes:
    “…Code however you want. I don’t care, even a little.” and “If you don’t understand how statements in JavaScript are terminated, then .. you definitely should not tell anyone else how to write their JavaScript programs.”
    I guess you just did that, sort of.

  36. Great post! There’s a 5th, and oft overlooked REST method called PATCH that’s extremely useful. While PUT replaces the entire item, PATCH can be used to update single components. Great for reducing data transfer and unnecessary rewrites.

  37. “Semicolons are actually optional” controversial.

    Brendon Eich, “The moral of this story: ASI is (formally speaking) a syntactic error correction procedure. If you start to code as if it were a universal significant-newline rule, you will get into trouble”

  38. I agree with most of them, I also personally don’t like comma first style but to be fair there is a good reason why they do it. The reason is when you add to a list you have to add a comma to the last item and then on the next line the new item of an array, object, etc. Not so bad except now in Github you have touched two lines and there is no way to tell that you only added a comma.

  39. Is it really bad to use semicolons though?

    I use them, not because of some standard or recommendation, but simply because I’m accustomed to doing so and it’s in my muscle memory. Are there any actual drawbacks?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.