When should I use Node for back end?
atulr.com
atulr.com
I've been working on a NodeJS backend at my main gig for the last two years.
For two years before that I was working on an backend application written in C#.
Based on my experience with those two systems, the answer to the question "When should I use Node for the back end?" should be: Only if your main language is javascript and you don't have the time and/or inclination to learn something else.
For me, working with C# was massively more productive. Static typing, robust async/await, and the fantastic tooling you get with Visual Studio + Resharper are huge benefits. Dynamic typing, callbacks and/or weird promise logic, and dodgy open source libraries which may not be very well documented or maintained are huge downsides for Node JS.
I would never choose to write a new project's backend in Node JS.
YMMV.
The single-threaded nature of node.js was very intentional and was thought to be a better design choice for a certain class of applications (IO focused, not computation focused) like routers, web servers, and other networked applications.
Promises/async were needed to make the language usable because it's stuck on a single thread. The normal solution is to just use multiple threads and people have been doing g that for many years in other languages
But, this was intentional. As for them implementing threading, I am not sure about the history here. Was it like: "We used JS and knew we were going to have a ST environment, but because people wanted MT, we tried..."
Or, was it more like: "Let's use js and we'll of course need MT like everything else... oh wait... nvm."?
Js is single threaded because it was designed that way, not because it's a good design
You're defending the single threaded model as if multithreading is a problem but it's just a feature. you could choose not to use it if you don't mind the performance penalty, just like async.
Node not having multi thread support is definitely a negative.
But why would you need threading? 99% of the time will be spent waiting for io. And you can allways spawn a process if you need something computationally heavy.
If you max out the core running your node thread, you are just about to need a second machine and load ballancing anyway.
With noexplicitany and strictnullchecks, you can get really nice, typed code.
Even stringly typed code can be typed now, with keyof.
But when you say "callbacks and/or weird promise logic" I can't help but cringe a little bit. Syntax really depends on what the developer is familiar with.
When you get used to the syntax, and use a decent editor, the syntax is a less important consideration -- a for loop is "fo + enter" in every language. The base libraries and API are important, but I don't consider that syntactical. That said, some languages lend themselves better to certain styles of programming -- but that may be a matter of flavor as well.
From the guidelines:
Please don't bait other users by inviting them to downvote you or announce that you expect to get downvoted.
https://news.ycombinator.com/newsguidelines.html
If you think you might get down voted, take extra care to ensure you're expressing your thoughts clearly and civilly. There are those who will down-vote regardless, but you can "decrease the attack surface" by writing the best comment you can.
Downvotes aren't usually from a lack of civility. They are from saying something that contradicts other people's worldview.
My view is that you're always more productive in the language you know better. I find things like being able to use functions as variables tremendously useful in JS. Not to mention the ability to share code between the back and front end of a webapp.
A thing in C# for 9 years now.
> Not to mention the ability to share code between the back and front end of a webapp
Technically possible if you care to do so, but TypeScript + a framework with bindings should be good enough on the front end to not have to completely tear down your conception of what you're doing when you move from front to back.
But, for instance, IronPython and IronRuby are compiled, yet dynamic, and GHCi is a Haskell interpreter that runs an extremely strong/static language.
The point is that node is not that fast. If performance is paramount don't use it. Node really shines when you need to use client side libraries on the server. The two best uses I've seen is server side rendering of pages and html5 canvas for browser based painting apps
EPOLL / NIO is still great for stuff like HTTP front-ends.
But there's also factors like the slow loris attack, where malicious clients hold a connection open and send a few bytes at a time, never completing the HTTP request. For these attacks, it makes sense for client connections to use the smallest amount of server resources feasible.
My experience matches the TechEmpower benchmarks, which you should check out here: https://www.techempower.com/benchmarks/ . They didn't get much discussion when posted.
Node is nowhere near raw netty performance in most situations and will never be. Js is single threaded, dynamically typed, and doesn't have low enough level access to the OS. Netty has a native network IO interface on linux.
Node is pretty respectable but netty is basically the fastest thing there is unless you're doing C. It even uses native zero copy buffers with the ByteBuf implementation, something js doesn't (and cannot) do with its dynamic typing.
The JVM has had a much longer period of relentless optimization and the language was designed to be well optimized. Js will never escape the performance penalty of dynamic typing and other decisions without a rewrite
I personally like Go more these days because it doesn't have these problems, it's very easy to do concurrency, and it's memory overhead is much lower. This in contrast to my other favorite option, python, which is a nicer language imo, but it's concurrency story is worse and memory overhead is about on par (varying from case to case, but my point being they're both much more than Go).
Node is kind of like an airport. Airports let you order food, alcohol, and even other cities. But as soon as you order, all of the work is offloaded to a third party -- the restaurant, the bar, or the airplane -- allowing the airport to handle someone else.
Here's a more verbose article on the topic, circa 2013:
https://www.toptal.com/nodejs/why-the-hell-would-i-use-node-...
I would choose it over Python or Ruby, because Typescript and Flow are great type systems.
Source: lead node dev / CTO since it came out. Currently using Haskell for all new projects.
Would you mind saying where you work?
Also, when/if GraalVM becomes public, would Node then be more suitable for CPU intensive apps?
I love javascript but never quite grok'd it as a server side language. I wouldn't mind using it, but have never found a good use case and this article hasn't really convinced me to delve into it.
Edit: I have found that it has been pretty neat for some command line integrations, but lately, I have been falling back to Ruby.
I really have no idea why anyone would take a language as terribly designed as JavaScript and try to put it everywhere. Non existant typing system, crazy semantics, and lack of true multithreading will always make it second rate to the others
I saw this video (https://www.youtube.com/watch?v=lYGfD2H99Ls) earlier this year, would be interested to see when and if this could be implemented in the mainstream.
http://mrale.ph/v8/resources.html
Surprisingly, very boring, predictably shaped prototypey classes written in the "hidden classes" style they prescribe will JIT compile amazingly well. I think a lot of the fancy uses of JavaScript to roll types with mixins and traits or simply to sidestep needing the 'new' keyword to instantiate objects miss out on lots of performance benefits on V8.
Honestly, where does all the hate for 'new' come from? Prototypey classes work fine once you understand how to roll them/extend them, and 'new' is a real keyword in the language, what's to hate?
- When a Firebase ref changes I listen to the event in Nodejs and update a full text search index elsewhere.
- When a Firebase ref is created I send the appropriate transactional email/push/sms.
- Do data validations before pushing to Firebase.
So in general, I do things that cannot/should not be done on the client-side while still opting for serverless architectures.
PS: Parse.com was great in that it had server-side code that was run on events like object updated/created. The code was NodeJS. In sum, it had lambda-like functionality already built-in. But Parse.com closed shop. Not sure if any of its spin-offs are offering a good service at decent prices.
Apart from that, I'm a JS hater, so I would personally always avoid Node - I neither like the language nor the server-side model, I don't think either one scales well, and there are better solutions out there for the server side (besides the JVM and .NET based stuff in the other comments, I like BEAM-based things like Elixir these days).
The real idea is don't do CPU intensive tasks in the event loop thread.
Instead, sometimes you use node native modules, sometimes you separate you child_process.spawn something written in Go, C++, or Rust(,etc), and sometimes you set up a separate work "queue" to pass work either on the same machine or over the network. I've used both kafka, zeromq, or even just files on the s3. A linux domain socket is nice too.
The WebWorkers and other approaches are about how to avoid using the IO thread to do CPU tasks. How the performance of those CPU tasks is depends on other factors. You can use WebAssembly or asm.js code to reach the performance of natively compiled code.
a) So you reimplemented all of the goodness of twisted in javascript? :) b) and you have to debug that new pile of code? c) with a language (in it's original form) that has a bunch of issues, despite being fun to develop in
Maybe Node with an ES6 backend? Maybe that's better. However, from my perspective, event based development works for some apps but is a total PITA for traditional workloads (websites).
I would think about Node for a messaging use case, or message processing.
https://github.com/LearnBoost/cluster - one I've used
In node you get sharing at basically the speed of TCP local sockets on the machine. So maybe 5GBps. With natively threaded languages you get sharing at the speed of the cpu cache, orders of magnitude faster
If performance is important enough that multithreading comes into play, don't use node.
i liked the package manager npm, but otherwise i prefer golang all the way for backend code.
Yeah we have ES(x) coming and typescript and node yay! All of the stuff coming to js has existed in better form in other mainstream languages for many years. Even stuff js still doesn't even have on the roadmap like multithreading, true static typing, and compilation
Are mainstream js developers really that ignorant of what is out there to suggest running js on the server all the time?
No. At least not the high caliber ones.
There are those that know only know JavaScript and will try to make everything fit. Although, you can say that about people who only know Java, or Python, etc.