Node.js is not a cancer, you are just a moron

My tone is going to seem strangely even and un-ranty. This is because I am doing everything I can to keep myself from completely exploding when I read this bullshit that this moron is spewing. OK, that was a little ranty, but the rest will read evenly. Maybe.

So one of my programming friends posts an article at http://teddziuba.com/2011/10/node-js-is-cancer.html and says, “Ah, here’s what’s wrong with Node.js!”

The article is rather strongly written – “Node.js is Cancer”, “node.js nonsense”, “Node.js is a tumor on the programming community”, “completely braindead”, “Scalability disaster”, etc.

He then shows a Fibonacci sequence and how it performs badly under node.

The problem he has proposed is, fundamentally, CPU-bound. I wrote a version of it in C and it did perform faster than it did in Node, but still, the problem definitely took finite-time. My command-line Node.js version calculated the answer in 8 seconds, the C version did it in 4. I was rather impressed that Javascript (Node.js’s V8 engine) was able to come as close to C’s performance in pure CPU-bound execution.

The problem, and what the author perhaps misunderstands, is that this is not the situation in which Node is an ideal solution. I use Node.js in production for work – and I know of many other shops that do too. If the problems you are dealing with are CPU-related, Node.js will not help you. Node.js works well when your problems are I/O-related -e.g., reading something out of a database, running web servers, reading files, writing files, writing to queues, reading from queues, reading from other web services, aggregating several web services together, etc. The reason that this solution has become so popular of late is because these are the types of problems that are most common in web development today. Thus, node.js becomes a helpful arrow in one’s quiver with which to solve these types of issues.

Considering that the article’s author seems to have some level of experience, I wonder if his choice of skewed example was perhaps deliberate. He has other articles on his blog about other event-loop libraries. His comment at the bottom – “tl;dr – Node.js is an unpleasant software library and I will not use it” – is possibly the real source of his anger. And – an irrefutable point – if you don’t like something, you don’t want to use it, and he obviously doesn’t. That’s fine.

Node is a tool; one of many – no panacea. If you’re dealing with problems of ‘slow’ services that need to wait for various bits of I/O to complete in order to return a result – it can be a very powerful and useful tool. If you’re computing the fortieth member of the fibonacci sequence recursively, it won’t be.

The sad fact is that the author’s completely valid point – that Node.js isn’t a good tool for CPU-bound problems – is completely buried in his bile. This is because he never states that, explicitly. Node.js has other drawbacks as well – it’s very easy to end up in callback-spaghetti, it’s very minimal, and it’s very very very young. The database integration libraries have some pretty serious immaturity issues to work through; and I’ve had to code around a good deal of that.

It’s a tool that’s good at particular things, and I will continue to use it for those things. Those ‘things’ tend to be the bulk of what web development and web services development actually are. So when I can write a two hundred line program that can replace entire arrays of servers and interconnected services with just one server; I am going to do that, and I won’t feel particularly braindead in doing so.

21 thoughts on “Node.js is not a cancer, you are just a moron”

  1. Interesting point of view. Just a question: being mono-threaded Node.js is good for transmit/recive small informations, not big files, right? For large quantities of data (as an FTP or a email with attachments) a threaded server is a better solution. Am I wrong?

  2. Good question – no, actually it does work pretty well for receiving very large files – each 'block' of information becomes an 'event'. Also good if you wanted to do something like display file upload progress in a pop-up window or something like that. I think the guys who make the Node.js MySQL driver actually run a business doing something like that.

  3. Thanks for this article. I am an experienced client side developer and my javaScript is quite strong so I was considering node.js (rather than toiling with php which I am not too keen on) but was put off by the node.js-is-cancer article. It is very irresponsible of him to write in such strong terms about this issue, without being 100% sure. But I suppose he got the attention that he was seeking. Anyway, thanks for setting the record straight. I will probably stick with apache/zend/php for now, because it is good experience, but it is good to know that node.php is a great option for the future, especially for someone with good js.

  4. @Nat: Oh, he's 100% sure. He's also 100% wrong. I wrote this elsewhere, but: if you have CPU-intensive tasks, you delegate them. Any web framework that can handle persistency will do the same thing the node.js does (Tomcat, Passenger, FastCGI…). They all have Apache/nginx in front, since they, as well, are very good at what they do, and it'd be stupid to reimplement all that again and again in Java, JS, Ruby. And while JS is not ideal, it's fixable by CoffeeScript, you can share code between server and client (e.g. use the same function for validation), it is ubiquitous, it's fast, and getting faster and faster due to browser wars.

  5. Yes, it's possible to delegate to a separate task. But it's not trivial, and it's not where Node shines. The naive implementation of the problem in PHP (for example) would scale fine across cores, scale to any number of simultaneous connections (within the scale of the machine), and generally would perform as expected.

    To do so in Node.js – you'd have to spin out a threadpool or process pool, or fork/spin up a new thread for every request – and collect the results back from your dependent process and return them. It's doable, but it's not something I'd do in Node unless there were some other advantage to doing it that way.

    So, yes, it's not impossible. I'm just saying it's not where Node works best – lots of I/O tasks – especially slow or network-based ones.

    I try to stick with 'use the best tool for the job.'

  6. Node.js isn't a cancer because it cannot perform a Fibonacci sequence in under 8 seconds. Node.js is a cancer because it is based upon the cancerous web-tumor known as Java(ECMA)Script and the justification is to eliminate language and platform diversity. Language diversity is important as different languages are suited to different problems. JavaScript has become a nightmare. Once intended for simple tasks to boost HTML interactivity, it has become an evolutionary sequence of hacks and band-aids. How many years have ECMA specifications lacked modular support? It's a joke, but worse mountains of production code is written on-top of this language that has NO modular support and a hack-job object-oriented paradigm. It has become an ugly language that makes my eyes bleed because of the bottom-up design strategy.

    JavaScript was only ever intended to animate your grandma's rainbow marquee on her baking homepage. We need a lot more than JavaScript has to offer.

    CPS ala JavaScript isn't all that natural or readable or maintainable. It is more logical to take slightly more time to work with language overhead and implement a proper threading model in a language that catches 90% of your mistakes at compile-time with blaring sirens than spend hours hunting for bugs in JavaScript at run-time. From my view JavaScript fans are masochists, I don't understand how anyone can have so much affinity for the language.

    When forced to write anything in JavaScript I make sure I grab a pipe and put on my Sherlock Holmes cap and cancel evening plans with my girlfriend:
    1. Write code
    2. Restart server
    3. Refresh web-page
    4. Spend two-hours scratching your head looking for a typo in a STRING that drives certain FUNCTIONALITY.
    4. Repeat
    4. Explain to your boss why the project still isn't finished (and why you're so tired you can't count past 4)

    In a sensible language:
    1. Write code
    2. Correct compile-time mistake
    3. Repeat
    4. Arrive early for the meeting with stakeholders with enough time to relax and sip green tea

  7. "Node.js justifies the elimination of language and platform diversity" is a bit of a straw man, don't you think?

    I read what you're saying and I just get:

    "I don't like Javascript. I don't like loose/dynamic-typing. I find continuation-passing style (CPS (I had to google this)) in JS unnatural, unreadable and unmaintainable. I don't like it when a typo in a string causes something to silently fail, rather than throw a big exception." I may also get that you like compile-build-release cycles, but I could be misreading that.

    And I think you have some semi-valid points, and lots of opinion. Of course, nothing wrong with sharing your opinion – and nothing too wrong with wording it strongly.

    I … accept…Javascript, I think. I love loose/dynamic typing. I hate strict typing. I agree that CPS can get very unreadable very quickly; and that overly heroic actions are necessary to reduce that. I also hate when a simple typo in a string causes something to fail silently, but that doesn't only happen in Javascript, and Javascript doesn't require that code be written that way. I don't like compile/build/release cycles if I can avoid them.

    If I were building a large MVC-style app, would I use Node.js? Probably not, other tools feel like they'd be better-suited for the job. If I were building a service that blocked on lots of concurrent IO from lots of different places? I would and I have – with great results.

  8. You have to turn on some basic optimizations when compiling C code (for example -O2 or -O3). Your results are just questionable. My simple C code is in magnitudes faster than node.js (~0.08s vs ~1.5s). But the rest of article is fair.

  9. I think is not very hard to implement it really fast, even in JavaScript, if you are using accumulators (actually this is the hello-world of using accumulators)….The author just do it suboptimal on purpose as an example of how something supposed to run fast can unexpectedly hang.

  10. In the Fibonacci example, enabling -O2 or -O3 allows gcc to unravel the recursion into a tail call which runs much faster, so I wonder if this is a fair comparison (as much as I hate node.js).

  11. Obviously teddziuba also criticized the "event loop" model.
    There are many frameworks/libraries that use epoll(). For most languages:

    Perl: AnyEvent
    Java: Netty
    C: libevent, libev, libuv
    Ruby: EventMachine
    Python: asyncore, twisted

    And there are generally not known to cause "Scalability disasters".

    My Assertion is: epoll() based network IO is more scalable than Thread based Blocking IO.

    Hint: http://en.wikipedia.org/wiki/C10k_problem

  12. No. You can stream large files, like a large html document, or a video file, in the background with node-js, and it doesn't block the even't loop.

  13. U call guy a moron while the guy has unbreakable arguments that at the end you admited to be true….

    Who is a moron here??

  14. Did you try to think what is the problem raised by Ted?
    He speaks about separation of responsibility and UNIX service-oriented way of doing things, doesn't he?
    Then you say
    > The problem he has proposed is, fundamentally, CPU-bound.
    No, the problem is that you didn't get the problem.

  15. LMHO i'm afraid i'll have to agree with that as well. brady, no offense, i get where you're coming from, but (and i'm not trying to be hostile or anything, and yes this is just an opinion because i don't have the time to re-write what countless other JS haters already wrote much better than i could anyway and which is also based on all the facts strewn across the internet by all those JS haters just mentioned (i am referring to people who know CS such as Martin Fowler, Rich Hickey, Michael Fogus, Brian Ford, Chris Richardson, James Coglan (read his post re node's biggest missed opportunity here: https://blog.jcoglan.com/2013/03/30/callbacks-are-imperative-promises-are-functional-nodes-biggest-missed-opportunity/) and many many others who do know what they are talking about).

    actually, James Cogan makes such a good point i can't help but quote him briefly (hopefully this will tease you to his post in full as it is quite cogent and enlightening):

    'In light of Node’s stated design goal of making it easy for non-expert programmers to build fast concurrent network programs, I believe this attitude to be counterproductive. Promises make it easier to construct correct, maximally concurrent programs by making control-flow something for the runtime to figure out, rather than something the user has to explicitly implement.

    Writing correct concurrent programs basically comes down achieving as much concurrent work as you can while making sure operations still happen in the correct order. Although JavaScript is single threaded, we still get race conditions due to asynchrony: any action that involves I/O can yield CPU time to other actions while it waits for callbacks. Multiple concurrent actions can access the same in-memory data, or carry out overlapping sequences of commands against a database or the DOM. As I hope to show in this article, promises provide a way to describe problems using interdependencies between values, like in Excel, so that your tools can correctly optimize the solution for you, instead of you having to figure out control flow for yourself.

    I hope to dismiss the misunderstanding that promises are about having cleaner syntax for callback-based async work. They are about modeling your problem in a fundamentally different way; they go deeper than syntax and actually change the way you solve problems at a semantic level.'

    and yes i am aware Promises have been added to the latest ECMA spec … but after how many freakin' years? 15+? it's not like we didn't have better tools in all this time.

    anyhow, my personal gripe is with all those JS apologists like Crockford et al because instead of being a positive force for change, all they did is try to maintain the status quo and in effect prevent change.

    we don't need more of the same old crap. we don't need more bandaid and hacks. what we need is proper language design from the start. what we need is radical change and improvement.

    Google Dart tries to do that. Clojure and Clojurescript do that brilliantly. Haxe is another option and crossplatform to boot.

    JS is like a patient with multiple organ failures that has been in a coma for 15 years+ and whom the doctor continuously tries to resuscitate with more blood transfusions and body part replacements (that would be the tacking on of new features such as Promise) that the immune system keeps rejecting until the whole organism is not even human anymore and about to die a slow protracted death. enough already, i say. 😉

  16. My initial appeal for node.js was: if I have to learn JS for client, I don't want to learn another language for server. My background is c++, which I believe is even older than JS. (C++ is so much nicer than JS from a linguistic standpoint.) After reading the debate about node.js for hours on the intardweb, I'm still willing to take some time to learn it, but am fairly certain that realworld web apps that need to scale big fall back on custom built frameworks, probably written as multithreaded c++ programs with cURL or something. Total noob here if I didn't already give that away with my nativity.

Leave a Reply

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