Compare Leading JavaScript Functional Reactive Stream Libraries

RxJS, @most/core, and XStream

Fabiano Taioli
Nov 3 · 6 min read
Photo by Quino Al on Unsplash

About Functional Reactive Streaming

“Reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change [1].” — Wikipedia

At the foundation of every reactive programming application stands a library that offers data structures and operators to compose the data flow that models the solution.


Push/Pull

In push-based behavior, the program graph is ready and constantly listening to new input data. This is, for example, the case with an event listener on a DOM element: the relative callback runs when a new input event occurs.


Cold/Hot Streams

Reactive libraries offer the basis to compose our application business graph. When the graph starts running the input data, producers get connected and listen for input events.


Implicit/Explicit Time Modeling

As said, the base functionality of the reactive library is to implement the application data graph that reacts to input data and produces the desired output over time.


Sync/Async Startup

After the application graph is declared and instantiated, it is necessary to call a method to start observing for input events.


RxJS: Observable Boss

RxJS Logo
RxJS Logo
  • Current version: 6.3.3.
  • Stars and used by: 2.1K 2m.
  • Type support: Native TypeScript.
  • Push/pull: Push.
  • Cold/hot: Hot (can support cold).
  • Implicit/explicit time: Implicit.
  • API style: Static or dotted by pipe.
  • Native ES6 modules support: No. (Yes in v.7 currently in alpha.)

XStream: King of the Cycle

Xstream JS Logo
Xstream JS Logo
  • Current version: 11.11.0.
  • Stars: 1.9K.
  • Type support: Native TypeScript.
  • Push/pull: Push.
  • Cold/hot: Hot.
  • Implicit/explicit time: Implicit.
  • API style: Principally dotted.
  • Native ES6 modules support: No.

@most/core: New in Town

@most/core logo
@most/core logo
  • Current version: 1.4.1.
  • Stars: 223 (3.1K on the main project).
  • Type support: Flow and TypeScript definitions.
  • Push/pull: Push.
  • Cold/hot: Hot.
  • Implicit/explicit time: Explicit.
  • API style: Static.
  • Native ES6 modules support: Yes.

Benchmark App

For benchmarking, a simple graph network was replicated with the three libraries.

Imperative traditional version
RxJS version
@most/core version
XStream version

Speed Benchmarks

Benchmark.js was used to compare the three library’s speeds.

Ops/Sec (high is better)
  • XStream — 54.59 ops/sec ±1.46% (81 runs sampled).
  • RxJS — 51.58 ops/sec ±2.59% (80 runs sampled).

Memory Benchmarks

Memory management is equally important, if not more, than speed. In real-world applications, we are going to have hundreds of thousands of stream nodes. Correct and efficient memory management will be fundamental.


Recursive Memory Test

Recursion-based memory test app
Recursive algorithm (low is better)
Recursive algorithm (without imperative version, low is better)

Promise-Based Memory Test

Promise-based memory test app
Promise-based (low is better)

Conclusion

Three of the major functional reactive programming streaming JavaScript libraries were tested for speed and memory usage on Node.js.



Better Programming

Advice for programmers.

Thanks to Zack Shapiro

Fabiano Taioli

Written by

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade