I see a lot of crap online about how Erlang kicks node.js' ass in just about every conceivable category. So I'd like to learn Erlang, and give it a shot, but here's the problem. I'm finding that I have a much harder time picking up Erlang than I did picking up node.js. With node.js, I could pick a relatively complex project, and in a day I had something working. With Erlang, I'm running into barriers, and not going nearly as quickly.

So.. for those with more experience, is Erlang complicated to learn, or am I just missing something? Node.js might not be perfect, but I seem to be able to get things done with it.

  • 9
    Maybe I'm missing something, but isn't node.js a JavaScript library, and Erlang a completely different language? How are they even comparable? Jun 21, 2011 at 21:25
  • 3
    @FrustratedWithFormsDesigner, node.js is part of a recent fashion/hype of getting javascript on the server side, with a multi-threaded approach, so they are comparable
    – lurscher
    Jun 21, 2011 at 21:29
  • 5
    @lurscher: You can't compare Erlang (language) to Node.js (server side JavaScript). That would be like comparing Java (language) to Django (server python). Not to mention Erlang and JS are very different as well.
    – Josh K
    Jun 21, 2011 at 23:25
  • 10
    As someone who uses both erlang and node, they are definitely comparable in the problems that they solve Jun 22, 2011 at 1:48
  • 3
    @Noli there is a difference between node.js and erlang. You meant a comparison between node.js and erlang based webservers. Erlang has many users outside of web servers.
    – Raynos
    Jun 22, 2011 at 9:32

3 Answers 3


First of all, I agree with JUST MY correct OPINION's answer regarding learning Erlang. It's a mostly functional language (although concurrency plays a big role), and all of its features were added to go towards fault-tolerance and robustness, which is not exactly the same design goals as Javascript in the first place.

Second of all, leaving Node.js to get into Erlang is a bit misplaced. Node.js is a single server/framework that goes its way to do everything in an event-driven manner with the help of callbacks. Erlang has its own framework (OTP), but it's not on the same level at all.

If you plan on learning Erlang, I suggest my blog entry An Open Letter to the Erlang Beginner (or Onlooker) as intro reading before diving into tutorials.

The only thing you can compare Erlang and Node.js in, in terms of patterns and usage is how they are event-driven. However, there are two big major differences here. Node.js' model is based on callbacks bound to events. Erlang is based on message queues and selective receives. What are the implications in there?

First of all, if you do things in a callback-based manner, the only way you carry state around is to either have it global or get into continuation-passing style programming. Secondly, you have to care for the full event matrix yourself. One example of this is that if we imagine a very simple finite state machine: a mutex semaphore, event-driven.

The mutex semaphore has two states: locked and free. Whenever a given unit of computation (worker, process, function or thread) wants to gain access to the mutex, it has to fire an event that tells it 'I'm interested'. Now you have to care for the following types of events:

  • The mutex is free and you ask to obtain the lock
  • The mutex is locked by someone else and you want to obtain the lock
  • The mutex is locked by yourself and you want to free the mutex

Then you have additional events to consider, such as timing out to avoid deadlocks:

  • The mutex has been locked and you waited for too long, a timer to give up fires off
  • The mutex has been locked and you waited just for too long, obtained the lock, then the timeout fired off

Then you also have the out of bound events:

  • you just locked the mutex while some worker expected it to be free. Now that worker's query has to be queued so that when it's free it's handled back
  • You need to make all of the work asynchronous

The event matrix gets complex very fast. Our FSM here only has 2 states. In the case of Erlang (or any language with selective receives and async with potentially synchronous events), you have to care about a few cases:

  • The mutex is free and you ask to obtain the lock
  • The mutex is locked by someone else and you want to obtain the lock
  • The mutex is locked by yourself and you want to free the mutex

And that's it. The timers are handled in the same cases as the receives are done, and for anything that has to do with 'wait until it's free', the messages are automatically queued: the worker only has to wait for a reply. The model is much, much simpler in these cases.

This means that in general cases, CPS and callback-based models such as the one in node.js either ask you to be very clever in how you handle events, or ask you to take care of a whole complex event matrix in full, because you have to be called back on each inconsequential case that results from weird timing issues and state changes.

Selective receives usually allow you to focus only in a subgroup of all the potential events and allow you to reason with far more ease about events in that case. Note that Erlang has a behaviour (design pattern/framework implementation) of something called gen_event. The gen_event implementation allows you to have a mechanism very similar to what's being used in node.js if that's what you want.

There will be other points that differentiate them; Erlang has preemptive scheduling while node.js makes it cooperative, Erlang is more apt to some very large scale applications (distribution and all), but Node.js and its community is usually more web-apt and knowledgeable about the latest web trend. It's a question of choosing the best tool, and this will depend on your background, your type of problem, and your preferences. In my case, Erlang's model just fits my way of thinking very well. This is not necessarily the case for everyone.

Hope this helps.

  • More on reactive programming and doing it in JS: blog.flowdock.com/2013/01/22/…
    – Bart
    Jan 28, 2013 at 11:46
  • "because you have to be called back on each inconsequential case that results from weird timing issues and state changes." - in Erlang, you still do need to handle timers, and the fact that you do it "in the same cases as the receives are done" doesn't change complexity (at all). From my perspective (as an architect of systems processing billions requests per day), the only realistic differences between selective receive and node.js-style are (a) the question "what do we want to do by default" (with node.js processing events by default, and Erlang postponing events unless match happens)... Dec 30, 2018 at 14:12
  • ...and (b) readability, including amount of boilerplate (which is pretty bad in classical node.js, but became much better - and IMNSHO better than that of Erlang - with newly introduced await operator)... And in any case, these differences are pretty much cosmetic (in spite of zealots on both sides preaching otherwise). Dec 30, 2018 at 14:14
  • I agree on this point. I tried making a a messaging system using NodeJS. Anything related to timing issues with the state on the server turned into hell. Weird bugs that were near impossible to trace. Mar 17, 2021 at 5:37

Erlang isn't complicated to learn, it's just alien to the mindset that the Chambers Constant (99.44%) of coders have learnt as the way programming works. The problem you're facing are likely just conceptual disorientation rather than actual complexity.

Here are some of the alien features of Erlang that are going to bite a typical programmer:

  • Erlang is a (mostly-)functional programming language. Most common programming languages are almost militantly imperative.
  • Erlang's concurrency model is the Actor model. Most common programming languages use either lock-based threading or some form of "reactor"-based approach to concurrency. (I think Node.js is the latter, but don't call me on it – I have zero interest in JavaScript on any side of the client/server relationship.)
  • Erlang has a "let it crash" approach to coding with powerful runtime features available to catch these crashes, diagnose them and hot-patch them while the system is running. Most common programming languages endorse a heavily defensive programming style.
  • Erlang is almost, but not quite, inextricably paired with a large and mildly brain-twisting library of commonly-used architectures for reliable and stable servers (OTP). (There is a reason why Erlang is typically referred to as Erlang/OTP.) Further this library is built on the alien features mentioned earlier and is thus opaque to newcomers. Most programming languages have less all-encompassing libraries (Java EE notwithstanding) to work with and said libraries are, naturally, built on concepts that are more familiar to most programmers.

So, learning Erlang is going to be more of a challenge to most programmers than learning Node.js – especially if the programmer is already familiar with JavaScript. In the end, however, once you get past the conceptual barrier, I submit that Erlang coding is going to be less complex than equivalent Node.js coding. This is for several reasons:

  • Erlang's concurrency model makes logic flow far clearer than the typical "reactor"-style concurrency and makes concurrency far more stable and correct than typical lock-based concurrency. It is almost no problem at all for an Erlang programmer to drop literally thousands of processes in a typical program whilst dropping thousands of threads in, say, Java would be a nightmare of contention (not to mention the memory and CPU overhead involved) and the equivalent of maintaining thousands of separate states in a "reactor"-based setup would be a nightmare to read.
  • Being a (mostly-)functional language, Erlang is very much a "what you see is what you get" setup. Variables, once set, don't change. Ever. There's no OOP "spooky action at a distance" to confuse you: anything you work with is explicitly laid out in front of you. There's no inherited variables from X and no class variables from Y and no global variables from Z to concern yourself with. (This latter point is not 100% true, but it's true in such an overwhelming number of cases that it's good enough for your learning phase.)
  • The powerful facilities Erlang has for handling errors means you clutter up your code with less defensive programming, thus keeping the logic clearer and keeping the code small.
  • The OTP library, once you grok it, is an insanely powerful stack of common code that keeps your entire application regular and covers many of the issues and use cases of long-living servers that you likely won't think of until it's too late. The OTP library itself is, IM(ns)HO a good enough reason to learn Erlang.

Continue slogging away at Erlang if you can, and if you haven't done so yet, go visit Learn You Some Erlang for Great Good for a gentle and (mostly-)funny introduction to Erlang's concepts.

  • Thank you for this post. I'm reading through Learn You some Erlang now, and I'm halfway through the book, but I'm getting the feeling that I'll need to know all of it before I'll be able to really begin to do something moderately significant, and not just take it piece by piece
    – Noli
    Jun 22, 2011 at 2:04
  • 1
    Actually once you get into the concurrency parts of the book you'll start being able to do moderately significant things easily enough. Jun 22, 2011 at 4:00
  • "Erlang's concurrency model makes logic flow far clearer than the typical "reactor"-style concurrency" - I'd argue that while reactor async processing was indeed a mess for decades, with the advent of futures and especially of await operator it is not the case anymore. With await, you can have your ultra-lightweight coroutines acting "as if" they're kinda-threads (and I'm not sure about JS, but in C++ co_await is architected to scale not to mere thousands, but to billions of outstanding coroutines). Dec 31, 2018 at 7:19
  • "it's just alien to the mindset that the Chambers Constant (99.44%)" - and for any industry project, this qualifies as a Big Fat Problem. This Big Fat Problem would stand even if there wouldn't be an objective reason for unpopularity of functional languages (which I don't abree with, but this is a very different and long story). Dec 31, 2018 at 7:22

There are a few significant differences between Erlang and Node

The first is that node is Javascript, which means its a very common language that shares a lot of traits with languages that more people are familiar with so it is usually much easier to get up and running. Erlang has an often strange and unfamiliar syntax to most, and although as a language is is far simpler than javascript, it takes a little more getting used to due to its uniqueness

The second is that Erlang has a very particular shared nothing concurrency model, it requires you to think in a different way to solve problems, which is a good thing (TM)

The last important one is that Erlang was developed by a commercial company and open sourced after the fact, it was only 2 years ago or so that people could actually see individual commits in the source control and even now I dont think all erlang developers have moved to the public github repo for their development. node.js was built inside the community from the start, this means its community support is far far better, there are already far more libraries for node, more community documentation, more live examples, a ubiquitous package manager etc etc. Erlang is catching up in this regard but its still a much larger ramp to get up.

Node will let you program fun things pretty quickly and relatively painfree, it still has growing pains in regards to large applications that erlang have solved for a long time. Erlang will change the way you program and (imo) make you a better programmer, however it wont make life easy for you in the beginning. Both are fun in different ways.

  • 2
    Worth mentioning that Node's threads are also 'share nothing'.
    – Tamlyn
    Jul 8, 2015 at 21:10

Not the answer you're looking for? Browse other questions tagged or ask your own question.