RxJS’s Pros And Cons: Is It A Holy Grail Or A Nuisance?

Why RxJS as the core library for reactive programming in JavaScript continues to grow in influence and a handful of weaknesses to be aware of

BlogUPDATED ON December 7, 2021

John Adam K&C head of marketing

Author

RXjs Pros and Cons

RxJS (Reactive Extensions for JavaScript) is the fundamental library for Functional Reactive Programming (FRP) for a large number of popular JavaScript frameworks including Angular, React and NestJS. It features a whole rundown of handy operators that you can leverage to make your code more efficient, faster, and snappier! But let’s take a closer look at what makes RxJS such a good pick for your web development tech stack and dig deeper to define what makes the library stand out from the crowd!

RxJS is one of the key libraries each modern JavaScript developer should have in his kit. It’s a library that helps developers simplify the process of composing callback-based or asynchronous code. At the same time, it also has the potential to help you make your applications even more performant and efficient thanks to a wide array of effective operators featured in it. Keeping all this in mind, it’s fair to say that RxJS is the de-facto basis of any reactive application.

Popular frameworks including  Angular and NestJS actively use the concept of reactive programming, explaining why RxJS is such a popular choice of library with JavaScript architects. Today, RxJS is among the hottest libraries used in the world of web development. It is a functional and powerful tool integrated into a wide range of frameworks. Broadly put, RxJS makes reactive programming more appealing and approachable.

Since its introduction by Microsoft, which released it as an Open Source project, almost a decade ago, RxJS has evolved rapidly. Even now, it keeps gaining momentum. Here are some numbers that clearly indicate its huge popularity:

RxJS statistics

  • At the time of writing, the RxJS library has over 6 million (!) dependent repositories on GitHub;
  • More than 26,000 dependent packages on NPM;
  • There are almost 27.5 million weekly downloads from NPM!

Can We Help You With Your Next Web Development Project?

Flexible models to fit your needs!

RxJS Pros: why this library is awesome!

The number of dependent repositories, dependent packages, and weekly downloads of RxJS is impressive. However, is it always the best choice? Let’s take a closer look at this library’s most significant pros and cons to figure out what makes RxJS so cool!

RxJS is well established, stable and benefits from an active Open Source community

Without any doubt, the enormous success of RxJS we observe today is a result of many years of hard work, dedication, and thousands of improvements and fixes made by the large, active Open Source (OS) community that supports the library. According to GitHub, the first release in the current repository appeared in 2015.

 


Date when RxJS first released on GitHub (in the new repository)

 

But its development started even earlier – back in 2013. In the world of web development and JavaScript, that makes RxJS a nicely mature OS library.


Date when RxJS first released on GitHub (in the old repository)

 

Throughout the now long history of the project, there have been almost 7000 commits from around 600 developers. That’s a huge contribution!

High-quality API

Thanks to its graceful API, RxJS makes it easy to describe a complex stream of data more compactly. To support that, it comes with a comprehensive kit of standard entities (Subjects, Observables, and operators), which take on all the heavy lifting. The complexity of the process is relatively hidden from a developer, allowing them to focus more on the logic of the application being developed. 

RxJS’s role in Reactjs development

What does this mean for React developers? With a little experience, it is possible to significantly simplify workflow with asynchronous data flows. For example, with UI events, HTTP requests or WebSocket messaging. Respectively, this allows developers to save time and effort for other tasks.

RxJS usage example:

 

RxJS’s API stability is worth special mention – it’s top! JavaScript developers using RxJS can maintain backward compatibility for longer, giving users additional time to move from deprecated APIs to the latest. RxJS additionally provides its community of users with tools and instructions for semi-automated migration to any new major version release.

Strong optimization and protection against memory leakage

RxJS’s maturity and active OS community mean developers can be confident in the quality of optimisation. Over time and thanks to the contributions of the RxJS community, many subtle problems with the library have been solved. In particular, problems associated with memory leakage have been detected and handled properly.



RxJS’s memory leaks issues stats

 

Extensibility

Despite a comprehensive kit of standard operators, it may occassionally be necessary to eject repeating algorithms into new RxJS operators. This can be easily achieved by following the official reference documentation. YouTube tutorials also explain it well, for example, this video:

Minimal footprint

RxJS is known for its high-quality optimisation and modular architecture. Both characteristics also ensure a smaller footprint, meaning the production bundle will only contain those parts that are really used.

No third-party dependencies

RxJS is a self-sufficient library, which, unlike many other libraries, doesn’t rely much on third-party dependencies. As a result, its influence on a project’s size is optimal and depends on how much of it is genuinely used.


RxJS dependencies


Currently, according to NPM, RxJS only has one dependency – tslib, which provides Typescript support.

Another benefit ensured by the lack of dependencies is that it is fairly easy to adopt the RxJS itself as a dependency for other packages. For example, API SDKs, utility packages, server-side programs, webhook implementations, and front-end event managers as well.

Large, active community

One of the biggest strengths of the RxJS library is its sizeable and diverse community. Thanks to having such a responsive community, RxJS continues to improve and grow in popularity. Participants of the community help each other to handle the problems and questions on StackOverflow and Gitter.

Documentation

Although reactive programming and RxJS are generally hard to master, overcoming this hefty learning curve is made easier thanks to the library’s massive documentation base.  You can find plenty of official documentation, as well as community-driven resources that aim to provide a deeper explanation of concepts, best practices, patterns, and examples, on RxJS’s official website, helping users to boost their theoretical knowledge and applicable skills.

Regular updates and RxJS v.8.0

The last, but most certainly not the least, major advantage of this library is that it is well maintained. Updates pop up on GitHub regularly, making it a very reliable codebase. The most recent 7.4.0 version was released on October 6 2021. We are currently on the roadmap to v.8, which will see the deprecations where the team was able to add ESLint code transformations removed. That will further simplify the replacement of deprecated APIs. A smaller bundle size, in some cases, as small as 40% of the current size, is also expected as well as efforts to keep up with the latest versions of Typescript and JavaScript maintained.

One thing that is even more important than consistency of updates is that every new release brings an overall improvement of RxJS, making it even more powerful, performant, reliable, and convenient.

When does IT Outsourcing work?

(And when doesn’t it?)

RxJS Cons: Weaknesses to keep in mind

While RxJS undoubtedly has many strengths there are also a few downsides that have to be kept in mind:

Data immutability required

Any developer working with RxJS should clearly understand that the need for data immutability in the library is less a requirement than a concept integral to functional programming.

Reactive programming has many pitfalls itself and when this paradigm is applied to JavaScript,  problems caused by language features can raise their heads. In particular, the lack of native support for data immutability in JavaScript can force a developer to resort to third-party libraries and workarounds which can be tricky and inefficient.

The reactive paradigm works best in combination with functional programming. This symbiosis is neither new or rare in the world of programming and it is called “functional reactive programming” (or short FRP). It offers significant advantages such as ease of creating multithreading applications and effective consumption of computing resources. But like all paradigms, it’s not a “silver bullet”.

One way or another, modern applications based on the symbiosis of object-oriented, functional, and reactive programming are cherry-picking the best aspects of all paradigms.

Complexity of testing

It’s worth noting that the specific features of reactive programming mean a developer needs to master an array of additional tools and techniques to test RxJS code.

As we are dealing here with asynchronous code, there is no way to get around testing without using additional tools. Luckily the RxJS team came up with their own custom solution –  Marble diagrams. The key goal of this tool is to allow for well-integrated data streams. Unfortunately, the need to use additional tools does make the process of texting more complicated. The syntax of Marble diagrams can be tricky, which means that developers still getting to grips with RxJS will have an additional learning curve here.

 


Anatomy of Marble diagram (source)

Strict typing issues

As mentioned, the only dependency of RxJS is tslib, which provides you with Typescript support. Typescript definitely brings a set of advantages such as strong typing, autocomplete, etc. However, users may notice some wrong usage of access modifiers (private/public), which makes internal methods accessible from the outside. 

Here is a clear example of this issue based on actual implementation (the method is usually hidden with a private or protected modifier):

export class Observable<T> { ... /** @internal This is an internal implementation detail, do not use. */ _subscribe(subscriber: Subscriber<any>): TeardownLogic { const { source } = this; return source && source.subscribe(subscriber); } ... }

In a perfect world, access to sensitive details of internal implementation in RxJS observable should be restricted, especially in classes that are part of a public API. However, they are not always restricted, which is a significant downside.

Operator names can conflict with other imported functions

The compactness of the RxJS code is a significant design achievement. However, there is another notable issue obscuring some of the benefits that brings. In the code, short names of operators (like map, filter, reduce) may conflict with other function names from other packages, for example lodash. Here’s a small example:

import { filter, map } from 'rxjs/operators';
import { filter } from 'lodash'; // Error. Duplicate imports.

Of course, such conflicts, though not ideal, can be solved with aliases for imported methods. But doing so is an inconvenience, which makes it a weakness of the library.

import { filter, map } from 'rxjs/operators';
import { filter as _filter } from 'lodash'; // Ok, imports have different names

Long stack traces

During the process of debugging, a developer may face the need to explore the stack trace of RxJS which can look daunting due to its size. That raises the question of why is it so complex?!

RxJS is built on FP principles including functional composition, partial execution, and delegation. Add to this the fact that data is passed through the stream and processed by operators, which delegates some jobs to given functions. The RxJS stream is a complex composite system, which leads to especially long stack traces.

Although especially lengthy stack traces can be overwhelming, or at least an inconvenience, the good news is that this is likely to change with RxJS 8.0. The RxJS dev team listens to the community and, where possible, takes measures to address or improve common complaints.

Conclusion

Wrapping up everything discussed above, the role of the reactive RxJS concept in the JavaScript ecosystem was pretty predictable. The library’s need is predicated on FRP’s maturity as a paradigm and that it works well with JavaScript features. Since its release in 2015, RxJS has been gaining momentum and helped shape other popular libraries and frameworks such as Angular and NestJS.

The model of operating the data streams offered by RxJS turned out to be successful and highly demanded. This encouraged the community to demand that this functionality be implemented in the ECMAScript standard. That decision has led to a big step forward in the library’s evolution, mirroring the evolution of Promise when it was added to the standard.

So, is RxJS a holy grail or a nuisance for a web developer? Our definitive opinion is that this library is a very solid solution for more convenient reactive programming. As such, it is definitely worth learning and implementing. And with the future promising increasing use of RxJS in JavaScript development, it is becoming an ever more vital part of a web developer’s tech stack!

If you’d like to discuss your development needs or an upcoming project with us, please do get in touch!

K&C - Creating Beautiful Technology Solutions For 20+ Years . Can We Be Your Competitive Edge?

Drop us a line to discuss your needs or next project