RxJS 9 API and import guide
August 1, 2026 ยท View on GitHub
RxJS 9 separates the platform Observable contract from RxJS capabilities. Import the root for intentional core primitives and import each operator or factory from its own subpath.
Root exports
import { AsyncSubject, ColdObservable, ConnectableObservable, Subject, behaviorSubject, connectable, replaySubject } from 'rxjs';
The root also exports notifications and public errors, including
Notification, TimeoutError, EmptyError, NotFoundError,
SequenceError, and ArgumentOutOfRangeError. Advanced code can extend
PerSubscriptionSubjectBase when it needs observer-local setup without
claiming that a Subject is cold.
Importing rxjs conditionally initializes the platform Observable surface. It
does not install every RxJS operator.
Symbol operators
import 'rxjs';
import { filter } from 'rxjs/filter';
import { map } from 'rxjs/map';
import { switchMap } from 'rxjs/switch-map';
const result = source[filter]((value) => value.active)[map]((value) => value.id);
Every public operator is a module-owned exact Symbol. Two independently evaluated copies intentionally have different Symbol identities, allowing version-skewed capabilities to coexist without overwriting one another.
When a platform string method has the same descriptive name, both forms remain available:
observable.map(project); // platform contract
observable[map](project); // RxJS contract
The RxJS import never replaces the platform string method.
The public subpaths cover transformation, filtering, combination,
higher-order, timing, buffering/windowing, error recovery, sharing/connection,
query, and terminal capabilities. The complete authoritative list is the
exports map; migration status and behavioral evidence are
in the generated ledger.
Factories and composition
Factories such as timer are static Symbols:
import { timer } from 'rxjs/timer';
Observable[timer](1000).subscribe(console.log);
The pipe Symbol supports instance and static composition:
import { map } from 'rxjs/map';
import { pipe } from 'rxjs/pipe';
const doubled = source[pipe]((values) => values[map]((value) => value * 2));
const normalized = Observable[pipe]([1, 2], (values) => values[map](String));
RxJS 9 does not install .pipe, publish RxJS 7 pipeable operator functions,
or restore OperatorFunction.
Construction and input boundaries
Derived RxJS operators use the receiver's construction protocol. Compatible
subclasses can preserve their result constructor; ColdObservable selects its
producer-per-subscription result contract.
Inputs cross the active realm's platform Observable.from boundary. Arbitrary
objects with a subscribe method are not automatically accepted, and
transparent foreign-realm conversion is not claimed. Review the
migration guide before translating RxJS 7 inputs or
lifecycle assumptions.
Cancellation and teardown
Subscriptions accept { signal: AbortSignal }. Operators own upstream work
through the downstream Subscriber lifecycle, and cancellation does not become
completion. Teardown functions and subscriber.addTeardown() participate in
the same platform lifecycle.
Environment and distribution
The package requires Node 22.13+ and publishes ESM only. Node require() uses
the supported require(esm) bridge and resolves the same module files as
import. Current browser, Deno, Bun, and Webpack support does not select
runtime-specific code. See release gates for the exact
matrix and budgets.