What's the difference between Knockout.js and Rx.js?

Solution 1:

Steve (the creator of Knockout) explained the difference on his blog:

I’m very familiar with Rx for JavaScript, having recently used it heavily on a big project, and in fact aspects of the design of Knockout are made with my Rx experiences in mind.

The key difference between Knockout’s implementation of the observer pattern and Rx’s is that Knockout automatically infers the associations and dependencies between observables from regular procedural code without you having to specify them up front though a special functional API. I wanted Knockout to use regular procedural/imperative-style code as it’s more familiar and approachable for most developers.

Another difference is that Rx is optimised for composing streams of events without state. At first I was enthusiastic about this and its functional purity, but after some time it felt increasingly like I was jumping through awkward hoops and had to invent extra ways to simulate state to manage UI commands efficiently. That’s why, in Knockout, all observables can be treated as stateful - for example you can always read their latest value (which is cached, by the way - it doesn’t recompute until the underlying data changes).

Rx goes further than Knockout into advanced ways of composing event streams, whereas Knockout goes further than Rx into UI development, letting you bind its observables to HTML DOM elements and templates and manipulate them any way you want. Rx is great at what it does but turned out not be be exactly how I wanted to build rich UIs - hence the design of Knockout.

Solution 2:

They're actually quite different frameworks, though I can see why you'd see crossover:

RxJs provides a means of composing operations against asynchronous streams, like events and web requests, and includes advanced scenarios like combining streams (when both A and B occur, start this, but cancel it if A or B occur again)

Knockout is an MVVM framework that allows you to manage the state of your user interface via a model that maps it's functionality. This allows your view's logic to be separated from your view.