The main selling point of Node was that it was JavaScript, and since you are going to have to use that on the front-end anyway, you might was well use it on the backend.
I've never seen anyone argue that callbacks are one of the easier ways of doing async.
No, the main selling point is that it's an event-loop based paradigm where all the APIs are async by default. As opposed to python twisted or ruby eventmachine where you have to look for async versions of the libraries you want to use and people writing modules usually aren't even aware that you want to be event-based.
Not the original point perhaps, but its come around to that. A couple years ago they settled on callbacks after a fairly active debate, as the least ambiguous option for continuation passing. As more people explore Node, callbacks are one level of abstraction too deep or just too tedious for some people. Fortunately there's a great selection of asynch modules to help them.
I really enjoy the callback paradigm. I love how powerful the abstraction of async code is. In procedural paradigm, there are some things that you want to accomplish that you simply cannot create an abstraction for, because the operation you want to do is time based. With the power of callbacks, you can abstract away complex things with a single function.
As AndyKelley mentions, the point was it being async and event-driven by default. JavaScript was chosen because it was the only language that was simultaneously popular and free of sync baggage.
It was easier until we discovered even cleaner ways, and most of the Javascript community began to adopt them. But node chose to stick to the "old" ways. (Not really old, but not as shiny and new as the alternatives)
I feel like promises don't need to be part of core though. It's easy enough to wrap the standard library in userland and just have other things depend on the wrappers.
ES6's generators and the `yield` keyword plays very nicely with callback-based code, doesn't require any changes to the underlying libraries and gives you a much nicer syntax to work with.
As the post said, there are plenty of libs that add additional functionality in place of callbacks. Let everyone choose the way that works best for them.
A lot of short node.js code snippets you run into on the web use anonymous callbacks, and I agree, that gets ugly very quickly, but if you bind callbacks to methods on prototypes the code remains pretty readable.
I agree 100%. But still, a lot of people are complaining about some of the Node.js API choices.
They are complaining because it makes programming more difficult , and the truth is , async programming is hard when it relies on callbacks.