>> - Node.js's "callback hell" async paradigm is probably the worst of any popular language/framework today.

Now we have Promises, so this argument has become completely invalid.

Even before Promises, avoiding callback hell was relatively easy - You could just define your functions one above another (even if you used callbacks) - nesting anonymous functions was NEVER necessary in JS - People just did it because they were too lazy to actually declare the function before using them.

>> - Ignoring the fact that JavaScript lacks static typing, its inconsistencies make it a pain even compared to Python or Ruby. It's so bad that entire applications are written in CoffeeScript and transpiled just to avoid JavaScript.

A lot of the main concepts from CoffeeScript have since been introduced as part of ES6. A lot of JS developers never understood the purpose of CoffeeScript - It was merely a gateway to encourage stubborn Python developers to switch JavaScript (and was very successful). A lot of CoffeeScript developers who did not like JS now like it thanks to ES6.

>> - NPM is an absolute clusterfuck. It's a matter of "when," not "if" your application will break because a dependency violated semver. Oh, and good luck developing offline.

The main problem was that some people wrote modules which had very wide dependency version ranges and this caused issues when a dependency would be updated behind the scenes in a non-backwards-compatible way.

npm has always allowed you to specify strict version numbers for your dependencies - I have always followed this approach but a lot of developers didn't. Since this issue came to light, you'll find that most popular modules now use proper semantic versioning or strict version numbers when referring to dependencies.

>> - The over-engineered UI frameworks and tooling have bled over and poured gasoline on the clusterfuck.

I'm sure that some projects are 'over-engineered' but you'd be surprised how often topics like 'the Linux philosophy' comes up in discussions between Node.js developers. Many Node.js developers are really conscious about complexity.

>> - A community with the attention span of a goldfish

I agree with that, the community is all over the place. I think part of the reason is that no consensus has been reached regarding a lot of things. That said, it has settled a lot in recent years. I don't think this is such a bad thing; better be unsure than forcing everyone in the same (wrong) direction.

>> - Scaling is a pain in the ass.

Moreso than Go, but I wouldn't call it a pain in the ass - I think it's a good thing. Node.js tries to stay small and compact so that it can easily fit into any architecture - This makes Node.js a really good match for third-party process managers and containers/Docker orchestration systems like Kubernetes/Swarm/Mesos.

It would be terrible if Node.js had its own scaling mechanism - It would probably conflict with those of orchestrators which have their own way of doing things.

I think that the Node.js community intentionally decided not to deal with scalability and to offload that concern to external process managers and orchestrators. I think as the Docker/Kubernetes ecosystems evolve, the decisions made by the Node.js community will really start to pay off.

I'm using Node.js with Kubernetes/Docker now to build auto-scalable stacks and it's mind-blowingly excellent.