Scott Nonnenberg wrote a great post about how Node.js is not magical.
Another good point that Scott makes: Taking the time to do tests right is hard. In my opinion writing automated tests is necessary for shipping good node code. As a developer, I try to include it in my estimate whenever possible. It’s been hard figuring out how to test all the asynchronous code, but worth it to make sure code works fully before shipping it.
If you’re just getting started with Node, see Scott’s post for some helpful links.
For me, Scott’s #3 (async by default) is the big gotcha. I just don’t think 80% of server code needs to be asynchronous. It’s not worth the complexity it adds to writing and testing your code. I always think code should be simple, not clever, and written for non-geniuses to understand. Computers are cheap, and brain power is expensive (at least for now) – so if you have a server-side function that retrieves data from a database, does a few other things, and then returns it to the client – it doesn’t need to be asynchronous to have sub 100ms response times.