top | item 3547476

If you're using Node.js, you're doing life wrong

139 points| fogus | 14 years ago |codeslinger.posterous.com | reply

93 comments

order
[+] irahul|14 years ago|reply
The Ruby and Python communities are just now, many years after the hype has faded, learning that stuff like dependency injection and proper modularization are actually good things that help you maintain code over time.

This remark is off the mark. Dependency injection, as in injection by parameters and injection by constructors are so obvious people do it sub-consciously. A fluff word isn't needed for it. As far as IoC containers are concerned, I don't see Ruby/Python communities using it, mainly because half of it is fighting static typing.

And people are learning proper modularization now? Seriously? Python/Ruby has proper namespaces(ruby doesn't have it), modules, classes et al. Like any other languages, Python/Ruby has it's share of programmers who write spaghetti code, and programmers who don't.

Again, if he writes AbstractConnectionDepenencyInjectioManagerAbstractFactory and calls it proper modularization, I am happy Python/Ruby isn't picking it up.

[+] Daishiman|14 years ago|reply
Seriously, at least as far as Python goes it has always donde modules and namespaces better than C++ or Java or Scala.
[+] bri3d|14 years ago|reply
Agreed entirely - I find that this is an old debate between people who "love Java" and those who don't.

I posted some commentary on the same topic last time Nick Kallen's infamous "I love everything you hate about Java" blog got posted : http://news.ycombinator.com/item?id=3287777 .

What it boils down to is that Java likes invoking the names of design patterns with all sorts of pomp and ceremony (look, ma, it's an AbstractFactoryFactory!) while many more modern languages make similar design patterns natural.

Whether or not to like the ritual is up to the programmer, but I entirely agree that claiming that Ruby and Python are "just starting" or "don't" support patterns like dependency injection is absolutely baseless.

[+] crcn|14 years ago|reply
This was my first thought. Languages require different design principles. If you're calling JavaScript "spaghetti code", then you're doing it wrong.
[+] karterk|14 years ago|reply
Ok, as someone who has been actually building apps on Node for about 1 year AND working with a largish Scala codebase for the last six months:

> Not to mention the fact that its balls-ass slower than some straight un-optimized Scala.

I don't see the point of comparison here. Slower/faster is meaningless without the context. Apples to Oranges. And, Scala has it's own issues. Yeah, the JVM's performance is there, but bringing your team onto a Scala codebase is not easy either.

> It provides the least amount of aid and comfort to the programmer and its nigh-on-impossible to follow the code 6 months later.

Anyone who has developed more than a Hello World in Node will know that the problem of callback sphaghetti can be circumvented using events, promises and async libraries. Yes, until the language itself offers an async construct, this will be an issue, but frankly there are ways to get around it.

> JavaScript has very little support for any of those nice things: it doesn't even have namespaces, for chrissakes.

Client side JS has no module system. But Node.js has. At this point, I really wonder if the OP has actually worked at all with Node.

> It seems to me that people who are really crazy about Node.js are people who only knew JavaScript to begin with and to whom none of the above would ever even occur.

Another baseless claim. I urge you to go see the GitHub profiles of Node core committers. Seriously.

[+] rgarcia|14 years ago|reply
Nit: Client side JS has no module system.

Check out requirejs: http://requirejs.org/

I've used it to handle both server-side (node) and client-side module systems, and it's been great.

[+] jim-greer|14 years ago|reply
If you get really angry about the choices other people make for their own work, you're doing life wrong.
[+] zzzeek|14 years ago|reply
Approaches that become popular and highly publicized definitely impact everyone else's work in that field. Teams decide to migrate to those approaches, discarding others, based on perceived popularity, shallow impressions, small amounts of experimentation. Often, this is all we have to go on. But team members who have an intuition that the approach may have more problems than are first visible now have a choice, to either silently go along with the new decision, or to document their reservations. The anger is an issue though. It's a product of when you perceive a waterfall of hype crashing over your own perception of better judgment (please note: perception. subjective viewpoint). It's worth it to try adjusting those perceptions since anger doesn't really get you anywhere.
[+] pnathan|14 years ago|reply
Eh.

It's not limited in scope to someone else's work. I have done a decent review of a number historical computer science papers, I can confidently point to a number of things that have been pointlessly reinvented over the years at least once, if not 2-3 times.

It's like, why are people using these really bad technologies (node for instance)? There are are solid and advanced technologies that have done all these things, been tested, used, and developed over a long period of time, without the limitations of this newness and lack of features/testing/experience.

As a stupid example, a tracing simulator describing variable usage and coverage were commercially available for Fortran in the late 60s. I haven't heard of similar systems for C or C++ in my casual reading on C and C++. Perl has spent years working towards something that is starting to look a good deal like Lisp in Perl 6.

For node.js and golang and other asynchronous & message-based languages/platforms, see occam.

Why can't we look into the 70s and build new technologies instead of reinventing the same ones over and over again? That's why I get a bit miffed about new stuff that is the same as the old stuff, except Now For Modern Computers/The Web/Mobile/blah.

[+] zobzu|14 years ago|reply
if its your company's people choice, and thus that impacts you directly, you're actually doing life right.
[+] mjwalshe|14 years ago|reply
Amen - I quickly learnt node.js to build http handler for the callback element of a tool I am building using authority labs - for what we need its the dogs nuts.
[+] andrewvc|14 years ago|reply
I'm really pretty anti-node, but this article isn't very good. The concerns here are mixed up and not very thorough. All these points need graphs, charts, something solid to anchor them to. This is the sort of article that polarizes, but doesn't add to the discussion.

It starts off strong talking about a high bug count, but never gets into specifics there.

As far as scaling across cores goes, it's disingenuous to suggest that node can't do this, there are a number of options here. Message passing, for instance, does indeed work.

As far as nested callbacks sucking, I totally agree. But a walk through why would add a lot more substance here as well.

[+] mnutt|14 years ago|reply
I don't think it even starts off strong with the bug counts. That wasn't node, but using Chrome/v8 directly to parse web pages for their web crawler. I'm not the least bit surprised that parsing unfiltered HTML from the internet dominates their bug count.

I also won't be surprised if their rewritten scala HTML parser also dominates the bug counts.

[+] nephics|14 years ago|reply
Unfortunately, this way of stating unqualified arguments as basis for reasoning is quite prevalent on the Internet.

Keeping it to node.js bashing, this guy takes the discussion to a slightly lower level: http://youtube.com/watch?v=1e1zzna-dNw

[+] substack|14 years ago|reply
> JavaScript has very little support for any of those nice things: it doesn't even have namespaces, for chrissakes. Why would I want to repeat these same mistakes over and over again in a new language?

Javascript doesn't have this (by itself) but node has a very nice require() system that is really excellent for long-term maintainability. When you bump a dependency in a node project that change will only affect the code near it because of how node_modules are resolved to the most local copy. You can bump dependencies without worrying how this will affect other packages.

Plus, require() just returns an object. It doesn't puke a bunch of objects into the current scope. This is massively useful for readability. I've sunk a lot of time on other systems tracking down unqualified exports to figure out which package's documentation to consult.

I've got nothing against scala and am sure it's a useful language but I wonder if the author has even used node.

[+] josephcooney|14 years ago|reply
How can we even be talking about node and long-term maintainability when it is about 2 years old? And require is younger than that?
[+] davidw|14 years ago|reply
I don't really have a dog in this fight, but I see node.js as being "disruptive":

* It's "not as good" as languages/environments like Erlang.

* But it's good enough, and significantly simpler, as an approach to tackle a certain class of problems. This, combined with widespread knowledge of Javascript, will probably make it fairly widely used.

[+] padobson|14 years ago|reply
I was waiting for the disruptive argument in this thread.

The fact of the matter is that Javascript is currently (and for the forseeable future) client side language that runs without a plugin. If you want your entire stack to run on Javascript, then server side programming is the only way.

Projects like CoffeeScript are the earmarks of disruptive technology - getting something that doesn't fit most peoples needs to grow up quickly, fit everyone's needs, and destroy its competition before the competition even realized it was there.

[+] cube13|14 years ago|reply
I disagree about it being that "disruptive". The concepts that it uses aren't new. They've existed in POSIX environments for decades.

At a very basic level, Node.js is a callback-based API that's based around some(probably select) notifier loop. That's not particularly new.

[+] didip|14 years ago|reply
Everybody is angry if bugs keep punching them in the face. I get that. But this post needs more info to be informative:

* If I read correctly, OP is using Chrome/V8 directly. I don't see if the bug list is on V8 itself or his bindings?

* "Callback Spaghetti". To each his/her own. I happened to read callbacks easier than other solutions. And this is coming from Python programmer, not JS programmer.

* The last 2 points are also information-less rants. What happened to HN?

[+] jessedhillon|14 years ago|reply
Here's my problem and why I don't care to use it:

It's a community built around an implementation of a language which they do not control. Who is Guido or Matz in node.js? Ryan Dahl I suppose; does he take requests or hold discussions concerning the future evolution of the language? Does he issue any rationale documents concerning his language design philosophy? Could he add multithreading to V8 and if so, why hasn't this happened?

It's a community built around someone else's tool, and Google develops it for entirely different reasons. Case in point, someone posted IcedCoffee, which adds an "await" keyword to CoffeeScript -- you have to implement a compiled language on top of Javascript to have the language features you need!

Finally, to preempt questions about my being concerned about other people's language choices -- other people are choosing, inexpertly in my opinion, the technologies with with I will contend in the future. Future employers may value and demand experience in node, and future employees may have to be disabused of bad habits accumulated during the learning of it.

[+] chc|14 years ago|reply
This comment is just wildly off the mark. You're comparing a framework to a language. DHH can't add features to MRI Ruby any more than Ryan Dahl can add features to V8 JavaScript.
[+] GnarlinBrando|14 years ago|reply
Issacs (the guy who built npm) is now the lead for node. Ryan Dahl has moved back to researching stuff or joyent. Your point about being built around other peoples technology is totally valid, but in regards to coffeescript I think it will prove useful as it will probably help steer development of JS itself.
[+] antrover|14 years ago|reply
It's posts like this that make me embarrassed to be a programmer. The author basically states, "Node.js is not a good fit for my company, therefor everyone using node.js is wasting their time." It's generalizations like this that just blow my mind.

I don't go around saying, "Snickers is the worst candybar, therefor anyone who eats a Snickers is wasting their time."

I bet the author is not a pleasant person to work with.

[+] virmundi|14 years ago|reply
I guess it depends on what I how I want to do my life. If I want to live my life by learning new ideas and using those ideas for something tangible, Node's a pretty good choice. If I want to live my life as a person with a particular language/architectual ideology, then anything that is not in that world view is wrong.

I like node for system level scripting. I find bash annoying and non portable to windows. I really don't want to have to learn batch scripting for dos on windows. But I can use JavaScript with node to script in both environments.

On the server I think that node might be helpful for certain network level tasks. But I haven't used it for much. But honestly what type of person would I be if I don't even consider it? The OP seems to be making an emotional decision rather than a technical one. Interestingly he's using Scala. There are many similar posts about Scala being the wrong way to do life. I just can't agree with any of those views.

Finally I wonder what the value is for these rage posts. They just seem to further divide people. I do see the value in the posts about I've used node for X months, here's my thoughts or here's why I'm going back to X paradigm. But just a rant where faces should be punched seems out of place for HN.

[+] brunoc|14 years ago|reply
If you like Node for system level scripting, you're gonna love this: http://www.jsdb.org/

Don't let the name fool you, it's not only for databases. I would say that it's probably more suitable for general purpose scripts than Node, though some of the APIs are a bit clumsy.

It's not open source, but it's free and cross platform and actually pretty good for a lot of general purpose scripting. Seems that it is developed by a single guy. I found out about it a few years ago and used it to get some things quickly done.

[+] hello_moto|14 years ago|reply
Article like this needs to be sliced-n-diced in different ways:

1) If you don't know technology X and use it due to hype, you deserve to get burned

Let that be a lesson for anybody.

2) There's no silver bullet

Choosing node.js over web-framework just because you want the front-end and the back-end to use the same code-base is to trade one feature for another: Ruby and Rails still have better tools than Node.js while you get JS all over the place (assuming you're good with JS).

3) Complaining about the language is a sign that you have no clue

I used to think that Java is better than some of the hype dynamic languages out there but I was wrong: Java is better for ME because I _KNOW_ Java Better. If I know Ruby more than I know Java then Ruby is better than Java FOR ME.

4) Don't program using another language's idioms

This is documented left and right already. If you use technology X, find best-practices for technology X. Don't just apply best-practices from technology Y.

http://dirtsimple.org/2004/12/python-is-not-java.html

Or some of the comments here about Dependency Injection (which is quite common in Java but not so in Python/Ruby).

In the past, I had one instructor that noticed that my QBasic code looked like Fortran. He asked me if I knew Fortran beforehand and I told him that I've taken Fortran before this class.

People see and notice.

[+] jconley|14 years ago|reply
Node enforces a programming model that puts you down the path to extreme vertical scalability, you know, actually using all the hardware you are paying for. CPUs and the kernels that manage them are good at running code. They suck at waiting for things to happen.

Out of the box the callback model can be difficult to wrap your head around. But if you are serious about writing a vertically scalable IO-bound service, it is currently the only option. There are some add-ons to make the code less ugly, but you still have to have the mental model down.

It's a lot like multi-threaded programming, or functional programming. It's a matter being able to visualize the flow and pass context around. This takes time to change the way you think.

If you approach problems in Node like you'd approach a problem in a functional language the spaghetti of callbacks becomes much less of a burden.

For the async haters out there operating at scale. How many of you have farms of machines with idle CPU's, maxed out memory, and practically idle network interfaces? Yeah, I thought so.

[+] tingletech|14 years ago|reply
Node is not for every use case,

This tech talk on node is pretty interesting

http://sna-projects.com/blog/2011/08/nodejs/

I watched it last weekend, and from what I understood/remember from the talk the reason the node people picked javascript was not because they liked javascript. It was because they wanted to do async programming, and they found other languages had too much synchronous baggage. In javascript, node.js could start from a clean slate and build a pure async culture and environment.

[+] brianshumate|14 years ago|reply
The problem I see with all these kinds of negative posts concerning Node.js is that they essentially boil down to "this is so radically different and uncomfortable to me that it cannot possibly be good for anyone else." and do not provide any concrete business examples of why it should be avoided.

Until I see an actual example of how "Node.js crashed my business, cost us N dollars, and here's exactly how...", I will continue to look at such posts as developers complaining about having to learn to do things a new way — something that has been going on since there were developers.

[+] robinduckett|14 years ago|reply
I have to agree with the rest of the commenters here. You make a blanket statement about something you've obviously never used. You're leveraging hearsay and third party complaints against a framework and language that you don't appear to be overly familiar with.
[+] hamidpalo|14 years ago|reply
The spaghetti code of node.js callbacks is really a problem of Javascript lacking monads, and in this case something like the Async monad from F#.

TameJS is a step in the right direction by adding a C#-style await.

[+] bunderbunder|14 years ago|reply
I've got my doubts about Node.js, since it seems like rather a one-trick pony.

But it is a good trick. Node.js deserves credit for calling attention to an underappreciated design pattern that has a lot to offer in certain circumstances. (Personally I think the .NET team hit the nail more squarely on the head with TPL, a pony that can do that trick as well as many others. But .NET doesn't have the sex appeal it takes to be a spokesmodel so meh.)

Javascript isn't my favorite language, or the most performant one. But as a "Lisp with C syntax", on a semantic level it's much better suited to the higher-order programming techniques that the pattern requires than most other popular Web languages are. Ruby also has the right features, but it isn't exactly the poster child for high-performance computing either. Might as well flip a coin, because either way opinionated folks with blood pressure conditions will call you an idiot.

[+] crazygringo|14 years ago|reply
Programming with Node's async model makes it extremely powerful and fast to run database queries and file functions in parallel, but the downside is the potential for huge callback spaghetti indeed.

But the callback spaghetti problem can be largely solved by dropping in, for example, the IcedCoffeeScript fork:

http://maxtaco.github.com/coffee-script/

Or the previous JavaScript TAME functionality:

http://tamejs.org/

There are of course many other async helper solutions as well, and if you're doing serious Node development, it's kind of insane not to use one of these.

[+] MatthewPhillips|14 years ago|reply
If you expect a lot of callback it makes more sense to design that functionality as an object rather than as a single function. That way you can spread callbacks over many functionality and still maintain modularity.
[+] libria|14 years ago|reply
I haven't used node.js before, but I see 2 main points being made about it, by proponents and detractors respectively:

* It uses non-blocking evented IO so it can scale well.

* It is single threaded so it can't scale well.

Someone teach me: which of these statements is true?

[+] ender7|14 years ago|reply
Neither are true.

Non-blocking evented IO is mostly attractive from a usability point of view: it's much easier to write programs that aren't multi-threaded. It can also use much less memory than a threaded model in certain situations.

Non-blocking, evented systems tend to be single-threaded. Single-threaded systems don't automatically scale across multiple cores. To scale, you spawn a separate process for each core (for example, this is the suggested practice for node). You must then find some way for the different processes to communicate with each other, which is usually through a database (or some crazy pub-sub thing).

Node can scale just fine if you design your program to do so. It just scales in a different way.

[+] bunderbunder|14 years ago|reply
Both.

If you're working on a project where I/O blocking is your primary performance issue, Node has a lot to offer in the form of a framework that helps and encourages you to structure your code in a way that works well for such tasks. Javascript's performance and its being single-threaded will have minimal impact, because those concerns are absolutely dwarfed by I/O costs in the situations Node's designed for.

On the other hand, if you're worried about how many threads you can run at once, then you're working on a task where CPU performance matters. That's not what Node is designed for. If you use Node anyway, you've decided to try hammering screws into place - and you should absolutely expect that it won't work out very well for you.

[+] sambeau|14 years ago|reply
They both contain some truth and some falsehood.

Essentially the first one is most right. Non-blocking IO can get a lot of work done as it is never hindered by doing nothing while waiting around for slow IO. It never blocks so it can always do work.

However, if a non-blocking system has too much work to do it can still max out a CPU. At this point you, ideally, need as many worker threads as you have CPUs.

However, a threaded system that doesn't use non-blocking IO runs the risk of having many blocked threads eating up a CPU & memory instead. This is largely dependent on the light-weight-ed-ess of the threads.

Both these systems are effected by how much work the server has to do to create a response, thus even non-blocking IO can become swamped if it uses a slow language, too much memory or the wrong algorithm, plus all IO must not block or else the non-blocking networking ends up waiting around for blocking files.

There are other complications too like the number of file handles a process can issue that can also impede a server and the number of clients it can simultaneously serve.

[+] jowiar|14 years ago|reply
It depends largely on what your scaling issues are. If you have requests that take a long time because of waiting for replies from web service calls, database calls, and the like, it will be a huge boon to scalability. If your CPU-limited, on the other hand, the non-blocking IO won't help you.
[+] tabbyjabby|14 years ago|reply
I think largely non-blocking I/O is a means to an end. Non-blocking I/O allows one to implement a single-threaded event loop, which allows one to skip all the overhead associated with multithreaded systems. It's not the non-blocking I/O which necessarily makes it more scalable, it's the fact that you avoid the heavy cost of context-switching and the memory and CPU complexity of thread creation.