Node.js is an amazing technology. Its key innovation is an event loop based execution model that facilitates writing programs that run with non-blocking operations. Here is an article on infoworld explaining that idea.
Nodejs combines two important programming ideas: event driven programming, and concurrency, in a way that is conceptually accessible for programmers to handle. If you can understand the following code, you can start writing programs in nodejs:
document.write("Round and round the cobbler's bench,<br>");
document.write("The monkey chased the weasel.<br>");
document.write("The monkey thought 'twas all for fun<br>");
document.write(". . . goes the weasel.");
Programming is all about building up previous ideas and performing them in a new and creative way. And that’s exactly what nodejs did. It took a messy and inconsistent language designed for web browsers, and, using google’s v8 engine, made it one of the most powerful and performant server technologies of that time.
When programming servers in nodejs, callbacks add complexity and can be a source of confusion, even when you are careful and design your program well. I would only recommend using nodejs as a server if the asynchronous non-blocking design is a critical part of the requirements of your system.
What are some simpler alternatives for programming web servers?
I consider each of these tools easier ways to write and maintain webservers in the long run than using nodejs. That’s my opinion and many may disagree with me, but it’s worth it to get familiar with your options and the tradeoffs involved. Notably, golang is the only strongly typed language that makes this list. GoLang has its own challenging concepts, but after the initial learning curve, I think it allows you to program simply when you want to, while the callback model of nodejs changes the way you have to think about programs.
It’s actually easier, in my opinion, to learn a new language than to master a new paradigm, ecosystem, and framework all at once. Everything in the nodejs server ecosystem has to be written asynchronously, because the threading model and good design make it a bad idea to combine synchronous and asynchronous operations. Async/await can improve clarity, but under the surface, you still need to understand what is happening asynchronously, as if it were written with callbacks. Otherwise, you may be hurt by the law of leaky abstractions. Asynchronous programming adds complexity and conceptual overhead to every step of the programming process, so be careful when you choose to use it.
If you decide to write your application in nodejs, it will probably take you more work than some of these other tools, but sometimes it is worth it.
While the concepts of nodejs are accessible and powerful, I think they are a more challenging way to design and build web applications in the long run, and may increase the difficulty of maintaining your web applications.