Demystifying RxJS by building it ourselves

Travis Kaufman
5 min readNov 27, 2019

--

If you’ve ever worked on an Angular app before, or you’re a frontend developer that’s interested in Reactive Programming, you’ve most likely worked with RxJS at some point. It is an extremely powerful library, capable of creating simple, elegant abstractions over otherwise tricky problems. For example, using RxJS you can implement auto-complete in a few lines of code. With all of this power, however, comes a world of complexity. This is especially true if, like me, you learned RxJS in tandem with trying to build an Angular app. Perhaps you’ve done — or are currently doing — the following:

  • Staring at sequence of operators within a .pipe() call wondering what in the world the code is actually doing.
  • Unknowingly triggering numerous unnecessary HTTP requests and just cargo-cult coding share() or similar in front of all of your Observable operator chains just to be safe.
  • Trying to figure out exactly what the terms “hot” and “cold” Observable actually mean, and why you should care
  • Continuing to look for documentation on outdated sites surrounding RxJS (the actual canonical site, by the way, is https://rxjs.dev)
  • Just given up and started using .toPromise() everywhere

Because of RxJS’s sheer breadth of what it does, coupled with the complexity of the problem it’s trying to solve, it can be extremely frustrating to write code because it’s really hard to tell what the code is actually doing.

I’m here to let you in on a little secret: while the library itself is complex, the fundamentals behind how the library operates are not. Beneath the sea of operators, the myriad of documentation, and the labyrinth of complexity, RxJS relies on a few simple key mechanisms.

While saying that is all well and good, chances are you’re not going to take what I say at face value, especially if you’ve used the library before. So in order to convince you that you can understand RxJS by understanding its fundamental mechanisms, we’re going to build an extremely simplified — yet functionally equivalent — version of RxJS ourselves.

Our own miniature library will be much simpler than RxJS itself, but will achieve the same underlying goal: facilitate reactive programming by allowing operations on streams of asynchronous data. By building our own version of the library, we’ll gain insight into the fundamental mechanisms that make the library work the way it does, and be able to use our newfound knowledge to utilize RxJS in our Angular apps — and anywhere else we use the library — in the most effective way possible.

In Part I, we’ll be building our own version of RxJS’s Observable class, which can be used for handling asynchronous streams of data in the exact same way RxJS can.

In Part II, we’ll introduce our own operators, allowing us to fully leverage the power of Observables. We’ll gain an intuitive understanding of what an Observable’s pipe() function does, and how pipe() actually works. Upon completing Part II, you’ll be equipped with the knowledge needed to use the library in the most effective way possible.

If you’d like to continue on, we’ll wrap up in Part III by building a very primitive version of schedulers, a more in-depth RxJS mechanism that controls the exact timing of how data is emitted from an Observable. This part might be most helpful for those doing more advanced RxJS programming, or who want deeper insight into how the library functions.

Intended Audience

I’m writing this primarily for Angular developers who are currently struggling to wrap their heads around RxJS. I was inspired to write this while working on a rather large Angular application, and found myself and my colleagues continuously running into issues trying to wrangle RxJS to do our bidding. It was at that point I decided I wanted to truly understand what was going on under the hood so that I could help myself and my colleagues, and what better (and more fun?) way to try and understand something then building it yourself?

That being said, I hope this can also be useful for anyone interested in Reactive Programming and using RxJS to build advanced data-driven apps. If your work includes building UIs for real-time data, or you do any type of front-end development where you’re dealing with a lot of “push-based” data, I hope this series demonstrates the value that a library like RxJS can provide.

This series is not for RxJS first-timers. If you’re unfamiliar with Reactive Programming or RxJS, the Angular docs on RxJS are a good place to start. Also, the YouTube videos Thinking Reactively and RxJS in-depth, both by Ben Lesh — one of the original creators of RxJS — are fantastic resources for wrapping your head around the library (funnily enough as I was researching this series, I found that Ben had produced a similar talk on building your own Observables for an AngularNYC meetup!).

Conversely, this series is also not for RxJS experts. If you are an RxJS expert, you’ll notice that I exclude and/or gloss over a lot. I’ve tried to radically simplify the concepts that make the library as powerful as it is, in hopes of distilling its core ideas down to their very essence so that people can have an easier time reasoning about their RxJS code.

…which brings me to my last and final point:

This “library” is for educational purposes only

My goal is not to show you how you can build a production-grade reactive programming library. RxJS already exists for that purpose, along with some others that solve this problem extremely well. We are building this toy library for educational purposes only. If you want to get involved in building a Reactive library, I encourage you to contribute to ones that already exist instead :)

Following Along

The best way to use this series is to follow along with it and write all the code you see yourself. I find that typing out code I’m trying to understand always helps me slow my brain down and really think about what it is I’m writing, and why it works. I put together this starter template on CodeSandbox that you can fork and use to follow along with. Or, feel free to just type the code you see into your favorite editor. Just make sure you copy over the code from the starter template so you can follow along!

TL;DR

If you would prefer to skip reading all of these articles, and just go to a complete implementation of the library, check out https://codesandbox.io/s/demystifying-rxjs-complete-implementation-5ib63.

With that, let’s begin with Part I: building our own Observables

--

--

Travis Kaufman

Software engineer specializing in UI / UX development. Proud New Yorker, lifelong learner. ⚡️Gryffindor ⚡️