Skip to main content

Introduction to RxJS

RxJS is a library for composing asynchronous and event-based programs by using observable sequences. It provides one core type, the Observable, satellite types (Observer, Schedulers, Subjects), and operators inspired by Array methods (map, filter, reduce, every, etc) to allow handling asynchronous events as collections.
Think of RxJS as Lodash for events.Just as Lodash helps you manipulate arrays and objects, RxJS helps you manage and transform streams of asynchronous events with ease.

What is Reactive Programming?

ReactiveX combines the Observer pattern with the Iterator pattern and functional programming with collections to fill the need for an ideal way of managing sequences of events.

Core Concepts

The essential concepts in RxJS which solve async event management are:

Observable

Represents the idea of an invokable collection of future values or events.

Observer

A collection of callbacks that knows how to listen to values delivered by the Observable.

Subscription

Represents the execution of an Observable, primarily useful for cancelling the execution.

Operators

Pure functions that enable a functional programming style of dealing with collections with operations like map, filter, concat, reduce, etc.

Subject

Equivalent to an EventEmitter, and the only way of multicasting a value or event to multiple Observers.

Schedulers

Centralized dispatchers to control concurrency, allowing us to coordinate when computation happens on e.g. setTimeout or requestAnimationFrame.

Why RxJS?

Purity

What makes RxJS powerful is its ability to produce values using pure functions. That means your code is less prone to errors.
let count = 0;
document.addEventListener('click', () => {
  console.log(`Clicked ${++count} times`);
});

// Problem: count is mutable and can be modified from anywhere
The scan operator works just like reduce for arrays. It takes a value which is exposed to a callback. The returned value of the callback will then become the next value exposed the next time the callback runs.

Flow Control

RxJS has a whole range of operators that helps you control how the events flow through your observables.
let count = 0;
let rate = 1000;
let lastClick = Date.now() - rate;

document.addEventListener('click', () => {
  if (Date.now() - lastClick >= rate) {
    console.log(`Clicked ${++count} times`);
    lastClick = Date.now();
  }
});
Other flow control operators include: filter, delay, debounceTime, take, takeUntil, distinct, and distinctUntilChanged.

Value Transformation

You can transform the values passed through your observables with powerful operators.
let count = 0;
const rate = 1000;
let lastClick = Date.now() - rate;

document.addEventListener('click', (event) => {
  if (Date.now() - lastClick >= rate) {
    count += event.clientX;
    console.log(count);
    lastClick = Date.now();
  }
});

Simple Example: Events to Observables

Normally you register event listeners:
document.addEventListener('click', () => console.log('Clicked!'));
Using RxJS you create an observable instead:
import { fromEvent } from 'rxjs';

fromEvent(document, 'click').subscribe(() => console.log('Clicked!'));

Use Cases

RxJS excels at:
  • Event handling: Mouse clicks, keyboard input, touch events
  • API requests: HTTP calls, WebSocket connections, Server-Sent Events
  • Animations: Coordinating complex animation sequences
  • Real-time data: Live updates, notifications, streaming data
  • State management: Managing application state reactively
  • Error handling: Retrying failed operations, fallback strategies

Ready to get started?

Install RxJS and start building reactive applications