← Back to context

Comment by azangru

8 days ago

> It (and also React) gets worse if you add a state system like RxJS.

I don't understand this sentiment.

Client-side applications often have a need for global state. It could be as simple as whether the user is logged in, or as complex as, say, the shapes that you have drawn in excalidraw canvas, and the drawing tool that you have selected. State changes over time, and so it seemed plausible to model it as a stream of states over time (hence rxjs). There are more robust ways to deal with the state, which is why angular has now moved to signals; but what is so bad about the state?

RxJS is far more robust than signals (things like backpressure operators, scheduling operators, and more). Angular's move to signals is just another sign of what Angular was doing wrong with RxJS all along: Angular could have used the robustness of RxJS to make a better framework but at many decisions along the way chose to not trust RxJS to do its jobs, skipped operators for the sake of leaking imperative state back out into the world and/or treating RxJS like heavyweight Promises (which indeed they are heavy and unweildy in that context). Signals enshrine the imperative leaks as the preferred and final path forward, further crippling the robustness RxJS could have offered and yet also doesn't entirely eliminate RxJS as a dependency.

Angular was born broken in how it made use of RxJS. A lot of developers have a bad impression of RxJS simply because Angular led them to so many RxJS worst practices, bad performance, and taught them that RxJS was just "heavy Promises".

  • RxJS has an intrinsic diamond problem (multiple events fired when several sources update simultaneously), which led to occasional glitches. Signals are guaranteed not to have that problem. This is a strong argument in their favor.

    But yeah; I am amazed and amused by how, during the past couple of years, the interest to rxjs has plummeted. No more conference talks on this topic. And even though Observables have been released natively, there is no activity in the rxjs repo to update the library accordingly.

    • As with most RxJS problems the diamond dependency problem can often be fixed/solved with the right combination of even more advanced operators/combinators. Often the easiest solution is `combineLatest`, but as mention that will over-fire depending on your update patterns. Sometimes a simple `throttle` is all the backpressure fix you need on that to reduce diamond over-firing, especially in combination with a cool scheduler such as `animationFrameScheduler` [0]. However there are also other domain-specific replacement options for `combineLatest` if you know the general event firing pattern such as `withLatestFrom`, `zip` [1], `join` [2], or `and/thenDo/when` [3] (in increasing complexity). (ETA: Not to mention that many diamond dependency problems are just fan out problems that can be solved by refactoring computations to an earlier point in the pipeline before the fan out rather than trying to fan back in.)

      > And even though Observables have been released natively, there is no activity in the rxjs repo to update the library accordingly.

      I believe this is still reversed: "native" Observables, the WICG Observables Proposal [4] is still marked as a Draft Group Report (not even officially a Proposal, still, ouch). The Issues of the RxJS repo still seem to indicate that everything is still in a holding pattern waiting for that to move.

      I still cynically think this is yet another case of WICG holding the football in front of RxJS and just as likely as Lucy would do to Charlie Brown, will pull that football again right as they try to kick it, again. The WICG has acted like there is renewed interest in Native Observables but my cynicism thinks they are just rehearing drafts on it to appease the Observables crowd just long enough to claim more interest/easier implementation in Native Signals and try to get a Native Signals Proposal passed without good Observables interop. (But again, I'm a cynic here.)

      [0] https://rxjs.dev/api/index/const/animationFrameScheduler

      [1] https://reactivex.io/documentation/operators/zip.html

      [2] https://reactivex.io/documentation/operators/join.html

      [3] https://reactivex.io/documentation/operators/and-then-when.h...

      [4] https://wicg.github.io/observable/

  • RXJS is also 18 MB which is irritating in a backend but completely bonkers in a frontend.

    • The entire npm package is 4.5 MBs uncompressed, and that includes a lot of files that won't be included in a modern bundle. A simple `npx esbuild --bundle ./node_modules/rxjs/dist/esm/index.js --outfile=./vendor/rxjs.js --format=esm` gives me a 141 kb file before compression.

      If you are seeing 18 MBs in your bundle from npm you may have more than copy or something else wrong.

      I will complain that RxJS still doesn't have a proper ESM build in 2026 for even better tree-shaking because that is apparently waiting on the WICG Observables "Proposal" to complete, and cynically I still don't think it is going to happen and I would love real ESM from RxJS someday like yesterday.

    • > RXJS is also 18 MB

      This is impossible. I think you are off by about a factor of 1000.