Editor’s note: This post was updated on 16 March 2022 to remove and correct outdated information.
Both Go and Node.js were first released in 2009 for the development of server-side and networking applications.
Go can solve a lot of problems ranging from systems, big data, machine learning, video editing and audio, and more. It also has the same performance as C because it compiles to machine code and doesn’t need a virtual machine or interpreter.
Before you dismiss this article as another “tech war or fight,” I suggest slowing down a bit and read on. This is just a comparison between Go and Node.js, where I will share the pros and cons of both.
So, while Go is a powerful tool, I’m not here to dismiss Node.js. Besides, it essentially depends on what you want to build with either.
Node.js and Go are insanely fast and good with multi-threaded programs (Node is single-threaded but it does the job very well, which makes multithreading unnecessary).
Okay, let’s quit playing around. In this article, we’ll look at the strengths and weaknesses of these two powerful tools, see how they approach different situations, understand their scalability, and answer the question, “Is Go overtaking Node.js.”
Node.js has been the most popular environment to build cross-platform applications with JavaScript. It helps build fast and scalable server-side applications with its great features like event-driven and nonblocking I/O model.
Go, on the other hand, is an open source, statically typed, compiled, cross-platform, fast, and multi-purpose language that provides concurrency at its peak, automatic memory management, and dynamic interfaces for structural type-checking.
Go is similar to C in terms of syntax and speed. It is also similar to C++ because it is compiled and a general-purpose language.
Not to bore you with these introductory or basics, both of them are popular and evolving and work best based on different projects, but we will delve into the pros and cons to determine which is suitable for your projects.
Go handles concurrency using coroutines, which are called Goroutines. These are functions or methods that run simultaneously with other functions or methods. Channels enable communication to avoid race conditions when dealing with shared memory.
Goroutines is a strong aspect of Go; if a large project needs to handle a couple of requests simultaneously, Go will perform. This, however, is not the case for Node.js.
Node.js is a single-threaded tool that uses the event callback mechanism. This means every function or method executes in a linear order.
A callback is a function that executes after a function finishes executing, meaning we can only decide to wait for the result of a function to complete later. So, Node.js lacks concurrency.
When it comes to concurrency, Go is the inevitable winner.
Unlike Node.js, which uses the exception method to handle errors, Go uses the explicit style. There are no unexpected uncaught exceptions. For example, for every Go project, you see the following code more often than not:
if err != nil { return err }
Might sound redundant to a Go outsider, but one of Go’s main goals is to take in errors as first-class citizens of each function, which is a “plan for failure, not success” mentality.
Using if err != nil
returns a value or error, it helps you note that failures must be treated first. There’s no need to wrap around try catch
, which handles every possible exception.
Another beautiful thing about linters is that they catch you when you ignore an error.
In regards to Node.js, error handling is indistinct and not explicit. The below code handles the error properly, but there is no explicit or proper handling of what went wrong. The error just goes to the console, disallowing full responsibility.
try { operation1(); operation2(); operation3(); } catch (e) { console.error(e); }
Go uses a disciplined and methodical way of coding when dealing with errors, and is the winner here.
Out of the gate, Go beats Node.js in terms of scalability because it supports concurrency, which helps handle side-by-side tasks. Go can manage 1000 concurrent requests per second, making Go superior.
Node.js’ weakness is that it works on the single-threading mechanism, meaning that tasks are performed one after the other, making it less scalable. However, it does allow concurrency with event callbacks, but these are not effective and far from parallelism.
This doesn’t mean that Node.js isn’t scalable as well, but Go does it better with concurrency and is much more memory-efficient. So, if you have a more CPU-intensive application, Go is where you should go.
According to the Stackoverflow 2021 Developer Survey, Go easily overtakes Node.js at an annual salary of $76,800 compared to $56,860 for Node.js developers.
At this point, this isn’t even a battle.
For raw performance, Go developers have said it shows the same characteristics as C and C++ in terms of speed and performance, which is really good.
With its memory management (garbage collector), it clears unused memory, thereby lowering security risks due to memory leaks.
Go is even suitable for building microservices due to its ability for handling heavy loads, high speed, and support for concurrency. The fact that it compiles down to a relatively small, statically-linked native binary that has relatively small, fixed runtime costs makes it fit to install in a Docker container.
Node.js, in terms of raw performance, isn’t that great compared to Go, but in live performance, everything works the same as with Go.
Go has fewer development tools than Node.js in terms of libraries and packages. This alone means a lot of manual setup still has to be done by the developer for Go applications, including thorough research.
Node.js has a large community that has provided many libraries and packages for developers. This large community also provides more support on platforms like Stackoverflow, contributing to higher productivity when building a product.
Node.js handily wins when comparing development tools and community.
Having compared both tools, Go and Node.js both have their pros and cons, but, notwithstanding Go’s performance, it seems Go is more reliable than its counterpart.
Go developers tend to have more pay than Node.js worldwide and error handling seems to be excellently handled, not that try catch
isn’t good, but having full responsibility for errors should be important to a programmer.
We should not forget Go’s race condition detection, which is a good thing when creating multi-threaded applications because some processes might complete in an unexpected order.
Also, Go is a compiled language that gives your app speed.
As you can see, Go wins a few of the battles but it is still hard to give the prize to it because it is hard to say which is better. It just depends on the application you want to build.
An application that must handle a thousand requests will simultaneously use Go to scale.
Also, while Go is also great and perfect for microservices and enterprise projects that must handle high loads, Node.js still has many development tools for every challenge, thereby reducing development time.
But, you might need to take into consideration the type of project (I keep repeating this), size, and structure to achieve your end goal.
Deploying a Node-based web app or website is the easy part. Making sure your Node instance continues to serve resources to your app is where things get tougher. If you’re interested in ensuring requests to the backend or third-party services are successful, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens while a user interacts with your app. Instead of guessing why problems happen, you can aggregate and report on problematic network requests to quickly understand the root cause.
LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. Start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.
Handle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.
Efficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.
33 Replies to "Is Go overtaking Node.js?"
Article is very inspirational to learn Go language. Yeah i am inspired.
But Go is a language and nodejs is a framework.
Why do we compare both?
The proper way to do this is Go vs Python or Go vs Js or Go vs C# Or any other language comparison 🤔.
I believe such comparison between languages is quite deceptive especially the title. A programming language may have better performance or better error handling than others. However, it’s pointless declaring it the winner if its an uphill battle doing certain projects with it. Its better to compare frameworks that solve similar problems than it is to compare programming languages.
Stopped reading at the description of Nodejs concurrency model. Anything to say about async/await or worker threads?
I was thinking the same thing. I am an old timer and back in the day I had to hand code all the threading (no helper stuff like promises and async/await). This guy clearly hasn’t or he would no that every program runs in the main thread and then you spawn other threads for concurrency. Exactly how node.js works with promises and async/await.
First koodos for writing article. People dont realize how much effort that takes i think.
I dont disagree with you overarching statement, dont think any programmer would. The tool is often decided by the projects needs. However you seem to make some false assertions on node end of things. Node while default is single threaded worker threads were added since mid 2018 giving it the ability for concurrence for example. Can also use clustering to take advantage of multi processor systems.
No intentions of starting a “no my language is better” war lol. Just trying to help inject information that was missing. Thanks again for article was good read.
Thanks for sharing!
With all due respect, this comparison lacks depth and it’s misleading. It’s mixing language characteristics with runtime engines.
For concurrency, Node is designed to be deployed in production as a cluster for HA. Something like PM2 will run a node process on each core allowing maximum parallelization and independent recovery. Error handling is a JS spec not Node. Anyway, it is much better in JS because you can have custom error types extending from Error and you can catch each type independently and handle as you wish. Also, you can have a global error handler. High pay might be true, but there are many more Node jobs. Go is a pretty sweet language, but JavaScript is way more flexible.
Go biased article I would say.
But appreciate the efforts put in .
Every language has its pros and cons we all can agree on that.
Node.js is a runtime for that matter.
Paypal, uber and many companies use node.js for their tasks because of its scalability and being able to handle much more requests in single thread which results in consuming lesser memory.
Where in traditional web servers every request is handled by a different thread this is much more efficient when it comes to i/o intensive application.
I must strongly disagree about Go being the winner in error handling. This is very application specific. While Go might be more disciplined, it also forces you to clutter your code with loads and loads of error handling scopes.
Javascript’s types errors allow you to keep your business logic flow completely clean and handle all errors by some error handler at the top of the scope. You can define different handling strategies for each error (DbError, ValidationError, AuthError, etc.) at a single point in the application.
Nonsense, don’t waste your time
you have more problems if you use them? 😀
Go and Nodejs can be compared against each other because developers need to make a decision to choose one over the other when developing their software.
Go and Node.js can definitely be compared and developers need to compare them when choosing tech for project. If I chose Go, I also get the Go runtime compiled into my app. If I choose Node.js, I’ll be writing my code in JavaScript. “Go” and “Node.js” each imply a language and runtime.
Informative!!
good language
nah, any language “implementation” is beyond a language. Go is not only a specification but also implementation including compiler, runtime, and ecosystem. So it’s perfectly valid to compare them as a whole.
Go does NOT have the same performance as C, they’re not even comparable. Just because it compiles to machine code instead of VM bytecode doesn’t mean it’s C level fast, the runtime garbage collector slows it down. This brings Go’s performance more in line with C#.
Very informative thanks for sharing, loved it
It feels like the person that wrote this article has little to no understanding of how modern node works.
First issue “node is single threaded”. Well so are a lot of language when you neglect the features that allows them to run on multiple threads. In node’s case it uses the cluster module to spread onto different threads. Node, like java, can also employ the help of native applications via the child process module. In theory allowing node and go to coexist.
Second is the “node is linear”. Unfortunately this statement is outdated with the advent of modern asynchronous JavaScript. Which the more I read about goroutines…the more they start to sound like asynchronous JavaScript functions.
On a broader spectrum. It might be worth bringing in one go programmer and one Nodejs programmer in for a debate when doing another one of these articles. As it would allow for a fairer comparison
Even if we ignore modern JavaScript, Node has always been able to run things in parallel. The standard modules have always been able to run things in their own threads with libuv.
It has ever only been the event loop that is single-threaded. Read a file – that goes to a worker thread. Write to a socket – that goes to a worker thread.
People who have written their Node code as sequential awaits or inner .then()s have, practically, ran Node as single threaded.
People who have used Promise.all etc have been writing concurrent code all the time.
“Node.js is a single-threaded tool that uses the event callback mechanism. This means every function or method executes in a linear order. [..] So, Node.js lacks concurrency.”
This is frankly very misleading.
Node has a worker thread pool, used heavily by the standard modules like `fs`.
The event loop runs a single thread and your JavaScript is executed by a single thread (well, not necessarily always true nowadays, but lets ignore the most recent developments).
But a lot of stuff you actually do ends up utilizing multiple threads. Read a file? That’s concurrent. Send a HTTP message? That’s concurrent. You can, 100%, do those things at the same time, even ignoring web workers or anything like that.
What you can not do is return to JavaScript from those functions at the same time. And what you can not do is call those functions from JavaScript at the same time. But they can, and do, run at the same time.
Great blog Thanks for sharing useful information
Still loving nodejs
Useful information. Thanks for sharing.
If You don’t know javascript nor golang the javascript is actually hugly more difficult then golang.
Javascript deals a lot with its past. E.g. You can declare variables using “var” or “let”/”const”. Both the options deal differently with scope. In ideal world, You only have let + const, but for BC You need both. And there is really lot of similar shit in javascript. Plus for some incomprehensible reasons, javascript tend to have way too many ways to do the same think in the end and You need transpiler (for typescript) to really have something usable.
On the other hand, golang is really minimalistic and unambiguous. Most of the time, there is exactly one way to do some thing.
I still don’t consider golang as the most comfortable language (more because its convention /community preferences kind of a punk culture, missing complex frameworks…). The other thing is, that as a golang developer You are more likely be expected to know devops+cloud-native-infrastructure.
I can see a lot more jobs open for nodejs then for golang.
Thank you for your kind words! I’m glad you found the information informative and enjoyable. If you have any specific questions or need further assistance, feel free to ask. I’m here to help!
Thank you for sharing, it was really interesting.
The Node.js community and ecosystem are undeniable assets. Finding libraries, tutorials, and experienced developers is much easier compared to Go. While Go’s strengths are attractive, I believe its wider adoption hinges on building a similarly robust community and resource library.
informative post shared.
thanks for shared information……
This is amazing to know.
Thanks for sharing very amazing and informative content
Nice Blog thanks for shairng and very informetinve blog.