In particular, it is preemptive. This... Makes a lot of stuff easier.
Instead of running a single VM with full knowledge of how to run lightweight processes, designed to fully take advantage of modern multi-core CPUs with multiple guarantees enforced by the runtime you have multiple single-threaded VMs awkwardly communicating with each other over a bolted-on API
It’s complicated.
Node itself has never been single-threaded. The execution model for JavaScript is single-threaded, so there’s no working around that, but libuv uses threads to build async IO on top of blocking operations.
Then there’s worker threads, which are pretty similar to web workers AIUI, that give you parallel execution for cpu-intensive work.
Obviously, though, none of these facilities compare with BEAM