There is more than just Node
I've spent some time reading articles here on codementor and I've seen a lot of love go around for Node.js as a platform. This praise is warranted, Node is a fantastic technology for getting a performant API running that connects multiple services - databases, other APIs, etc. I did this for several years in a few different projects, and even contributed some packages to NPM that are still in use today. The advantages of working purely in JS, the simplicity of interacting with JSON, and the massive number of libraries all make Node a pleasure to work in.
But there's one thing I've seen repeat itself over and over in the technology industry, and that is the nerdlove. Developers fall in love with technologies and forget that both other things exist, and that their favourite technology makes technical tradeoffs and sometimes those tradeoffs are not useful for the task at hand. I've run into some of these tradeoffs while developing Node applications, and I'd like to share some my experiences with that and remind everybody that there are other things out there.
I've also found that explicitly declaring your types helps to onboard new folks much faster, especially juniors. When someone is new they don't really understand what fields are available or what they do; your type declarations are useful documentation that does not go out of date.
Who is using TypeScript? Some notable examples eBay, Angular (and other parts of Google as a whole), Ericsson, and Kaggle. You can see many others on TypeScript's https://www.typescriptlang.org/community/friends.html.
Unlike TypeScript, Go requires all types to be explicitly defined, compiles to a binary instead of being interpreted, and unlike the underlying Node.js system that TypeScript uses, is multi-threaded. Because Go's goroutine system is so lightweight, it doesn't need asynchronous function calls to be fast. This is a huge win, since you no longer find yourself falling into callback hell, or having to mess around with complicated Promise chains.
When might you use Go? One of the major disadvantages of Node is that it is single-threaded, so if you have something that is CPU-heavy like string processing, number crunching, schema enforcement, etc. then your Node server will lock up while it's busy chugging away at that calculation. Since Go is multi-threaded, it can have some goroutines handling new connections while different ones manage the processing (which itself is much faster because of the native-compile).
Another advantage that Go has is its footprint. If you're running a large-scale setup on cloud VMs and you find yourself paying tons of money for them, Go might be a useful replacement for your widely deployed services since it makes much more efficient use of CPU and RAM than Node. An example from my experience was when I was running some socket.io-based chat servers on a Digital Ocean micro instance (512 MB RAM) I could only run 2 Node processes per instance before they started to run out of memory. Each Node process would use up about 200MB of RAM and about 30% of the CPU. Re-writing these servers in Go which only took a day or so, they would use about 10MB of RAM and less than 1% of the CPU.
Lastly, since Go is statically-typed then some of the same reasons that TypeScript is useful also apply to Go.
What are the disadvantages? Like TypeScript, Go has a build step involved, although you can run a program directly by using the
go run command-line tool. Build times are fast enough that it's not too different from running an interpreted program, but it is still an extra hurdle and can often result in some weird compiler errors when you are still new to the language.
In Go it's a bit annoying to use data structures other than arrays and maps since they have to be "dynamically" typed, you often have to fiddle around with casts to make the compiler happy.
A downside compared to TypeScript is that you can't just start using it within an existing Node application, you have to rewrite things. I have done this in the past, although since I was using RabbitMQ for my components to talk to one another, it was a pretty simple process of re-writing one module that was CPU-bound and taking too long. If your application is more monolithic, then you might have too many headaches untangling things to make a switch to Go worth it.
This is just a quick survey of two alternatives to Node. There are plenty of other new languages that pop up all over the place, but I chose these ones because at this point in time they are fairly mature and have proven useful in production environments, and they are often used in similar applications as Node such as REST APIs and server-side infrastructure. If you're like me and ran into growing pains as your application scaled up, then hopefully these choices help you out!