Blogging, Programming, Web Applications

An overview of Javascript reactive frameworks

This post is only meant to be a snapshot of the current state of the various DOM virtualising webframeworks that are around. I’m partly publishing it to try and discover more that I may not be aware of.

Many of these frameworks trace an ancestry back to Om and React. However each one tries to deal with perceived problems with the original frameworks. The most common being that React is too heavy and opinionated while not providing a consistent data model for components. Om on the other hand is in Clojurescript and therefore represents too much to learn in terms of a new language and build process.

Libraries

Most of the libraries build on a few common building blocks that I’m not going to elaborate on here. Virtualdom was an early attempt to separate the core idea of React from the rest of the library code. Virtualdom is only concerned with creating, manipulating and stringifying DOM structures in-memory. Browser DOM APIs involving linking to the actual rendered document so managing virtual DOM is more efficient and simpler because you’re not interacting with these underlying libraries.

ImmutableJS provides a Javascript-idiom interpretation of the Clojure data structures that Om uses (and which are available as the standalone library Mori).

Omniscient

The first interesting framework to discuss is Omniscient, which as its name suggests is heavily influenced by Om but is written in Javascript and therefore does not require you to learn Clojure to use the same techniques that Om uses. Omniscient is built on top of React and ImmutableJS and uses its own library Immstruct to add reference cursors to ImmutableJS structures. Reference cursors allow a component to observe and change sections of a data structure without having to manipulate the whole thing. So for example a component can be given a single sub-key in an object that represents its state and it cannot access or change anything that is not under that key. The code can also be simplified to behave as if the sub-key was actually just the whole data object.

Omniscient doesn’t suggest an alternative to Om’s CSP, instead providing a mechanism for passing event flow functions down the component tree. You’re free to choose your own event libraries. It also means that you’re free to make your own mistakes here as no guidance is really given as to how to structure your event scheme appropriately.

Omniscient is one of the earliest frameworks to re-implement Om and therefore has one of the better sets of documentation on its Github pages. That said there’s not a lot of documentation and the framework does not have a massive community. The situation is worse in most of the other frameworks though so this might tip you over in favour of Omniscient.

Ractive

This is a bit of a Guardian shout out as the primary developer Rich Harris is a Guardian interactive developer.

Ractive (Github) is a little be different from the other frameworks as you can essentially think of it as Mustache templates backed by Observables. You declare a data-binding and write templates in normal Mustache syntax but behind the scenes Ractive is driven by changes in the data and then writes new section of DOM in-memory according to what has changed rather than DOM diff’ing.

Also Ractive sticks with two-way databinding rather than unidirectional data flow so failures in synchronisation or rendering can be problematic.

If what you want to do is render content over a Javascript data model then there is a lot in Ractive that is very compelling. It uses templates with a standard syntax that is well understood and is a soup and nuts framework that sticks to core Javascript syntax and features. However if you want to use your own event or data model you are out of luck.

Mercury

Mercury on the other hand prides itself on modularity. A microframework it attempts to create a glue layer that allows other libraries to interact in a sensible and consistent way. The default components are Virtualdom and its own observer pattern to wrap state.

Mercury’s biggest problem right now is its lack of documentation. There is an expectation that you are going to read the source code to understand what the framework is doing and how to interact with the API. I frankly think this is unrealistic. The project doesn’t currently supply the incentive to do that. Unless you have a very particular desire to avoid any framework lock-in or you want to use a very specific combination of libraries that is not supported elsewhere its hard to understand why you would invest your effort here rather than in frameworks that offer more support.

Cycle

Cycle is similarly experimental, its biggest claim is that it is truly reactive and that the rendered page is purely the result of change in state. The introduction is couched in computer science theory but it would seem that at its heart Cycle wraps RxJS and Virtualdom in a glue layer that has the programmer writing the transform sequence between the event and the DOM structure.

I think it is a positive feature that Cycle re-uses a popular library to manage its state-transitions rather than implementing yet another custom version of the Observable pattern. It also makes the framework easier to get started with if you are familiar with the Rx.

Using established libraries also makes the lack of documentation more acceptable as the Cycle readme only needs to explain how the glue works in the framework.

As something built on reactivity you have to get used to dealing with intermediate state which can be bit difficult for the beginner.

Essentially any event where the user would expect feedback means you need write the conditional structure in the output. So if the user types a character in an input box then you need to write the value of the input box to be the characters the user has typed so far. Most frameworks work at a higher level of abstraction or rather they map closer to the DOM APIs, so getting a working application means grokking the way the dataflow works.

If you’re looking for purity (and a resulting simplicity in implementation) but not to have to learn a bespoke API Cycle is nicely positioned.

WebRx

WebRx is similarly built on top of RxJS Observables but is a much fuller-fat framework that is much more a spiritual successor to Knockout than owing much to the influence Om or React.

Rather like React WebRx doesn’t really provide generalised event handling but instead has special sauce bindings for DOM events and a MessageBus system built over Rx.

It is also written in Typescript and generally looks to play well within the Microsoft ecosystem. It’s interesting to me as an example of how different a language has to be before its regarded as a barrier. Clearly the use of Typescript means there are people who will refuse to use the framework regardless of whether it works for their use case. Other people are going to be attracted exactly because it uses Typescript.

Deku

Language choices are also interesting in Deku which is another attempt to re-implement React in a superficial way.

Deku makes use of ES6 and 7 features and doesn’t aim to support a broad range of browsers (unlike say Ractive). Again that is going to rule it out for some people but this is a more interesting as now we are within dialects of the same core language. Language choice for implementing frameworks is not straightforward. What are you looking for? Conciseness? Editor support?

Deku aims to take the dom diffing approach but avoid getting caught in React’s framework and approach. In particular components are defined just as Javascript objects rather that classes and instances. Something I think makes it more elegant that normal React Components.

It does however still use JSX which is quite interesting as the framework claims to be taking a functional approach but actually uses a DSL for all its DOM construction.

The lifecycle hooks are slightly different with more hooks for different stages of the process and Deku uses some interesting function passing to send changed data down the tree to components.

Deku doesn’t take much influence from Om though. It doesn’t have sophisticated event handling and uses mutable data with generous access and callbacks on data write to do re-renders. This means bugs and state issues are no less likely to happen than with any other framework. It does adopt the single atom idea with a single tree representing the app and the app renderer being bound to the body element.

As such if you like the idea of React but don’t want to bound into its concept of how a Component should be defined but do like JSX and trust the implementors to create a better dom diff than Facebook or Virtualdom, this is the project for you.

Conclusion

I’ve only chosen a handful of frameworks to look at here, mostly based on the ones I know, I’m expecting people to point out more in the comments. I also haven’t used all of these frameworks. Road-testing all of them would be a bigger task than just trying to describe the design choices they’ve made.

The most common pattern is to try and improve the rendering time versus React by using different virtual dom difference algorithms. Usually this is combined with Observed variables that provide a Reactive component that allows changes in the data model to be conveyed to the DOM model with no coding required.

Few of the frameworks engage with the functional reactive programming paradigm by building abstract event streams or indeed any abstraction over discrete events.

The idea that the app should be a single data structure that represents the whole page seems to be gaining significant traction with several of the frameworks recommending this as an approach.

The explosion of frameworks resulting from the release of React is, I think, a positive thing. Initially it seems really daunting that you have all these choices but when you look at the real level of difference between them you can see that they are actually quite tightly coupled around a few common and core ideas and that mostly they express differences about the concerns that a framework should have which feeds into the wider conversation about micro or comprehensive frameworks.

Standard

37 thoughts on “An overview of Javascript reactive frameworks

  1. Author of WebRx here: Even though the framework is written in Typescript, it is actually equally suited to be consumed in either Javascript or Typescript. Typescript user just get the static typing as bonus.

    • I think it is an interesting question as to whether the framework’s language matters as well if you’re not asked to interact with you.

  2. Pingback: Tech News / An overview of JavaScript reactive frameworks

    • Yes but not in this context, it’s really a very different way of approaching the problem. I think that comparing say Clojurescript and Elm might be more interesting but Elm really is a whole self-contained environment outside of the conventional Javascript ecosystem.

      • guest says:

        I realize that — hopefully there will be a blogpost about Elm some time soon 🙂

  3. luke9175921759 says:

    Clojurescript has a few alternatives to Om now. Reagent is the most popular after which there’s Rum and Freactive. As for other compiled languages, Elm must be looked at.

  4. jda0 says:

    Leo Horie’s Mithril, which I believe inspired Mercury, is a great and rediculously fast responsive framework which comes in at 12kB, and Muut’s Riot is a great alternative to responsive Backbone at 5kB.

  5. Just wanted to point out that Ractive’s two way binding is optional, you can disable it on a per instance level by setting a property to false.

  6. Pingback: Bookmarks for June 6th through June 7th | Chris's Digital Detritus

    • Meteor to me is trying to solve a very different problem and while it mentions reactivity in its feature list I don’t think it claims anything special technically in terms of reactive software design. Looking at the code it appears to being doing things with Listener pattern callbacks, which is pretty much the opposite of the frameworks I’ve listed here. If I was being unkind I would say that it was using the general meaning of the word to imply the technical one.

      I’m open to a rebuttal post or perhaps more information on how Meteor implements reactive code but its still not something that leaps to my mind on this topic.

      • Mário Rodrigues says:

        Hi RREES, You should check Tracker : https://www.meteor.com/tracker . Everything Meteor implements reactively uses it ( ReactJs integration is on the way in the next weeks/months ). One key difference from other frameworks is transparent reactivity, you can control if want to be reactive or not, It’s really easy to use Tracker without Meteor. Give it a try 😉

  7. +1 on Meteor. It’s using the DDP protocol to make all its client content truly reactive. And yes it controls the data flow via a pub/sub model, which may not be good enough for large and complex implementations, but it’s very powerful for streamlined apps and very fast development.

      • Depends on what kind of app you’re writing. A blogging platform? A Slack clone? Live-Editing or code collaboration tool? Meteor is perfect for that kind of thing.

      • Mário Rodrigues says:

        Blame the developers, not the tools. I saw great and terrible projects built with Meteor. So far the community reports that it’s possible to scale Meteor to large applications.

  8. Pingback: Links & Reads from 2015 Week 23 | Martin's Weekly Curations

    • There seems to be a consistent theme to the idea that this post was in some way about virtual doms, which are obviously part of the solution but I think if you still have mutable two-way binding data structures you haven’t really got the fully benefit of the approach that Om suggests.

  9. Dom says:

    +1 for Mithril, fast, lightweight, small API, makes you use functional programming, and it’s just javascript, you are not learning a new language…and vibrant community particularly on gitter

    • There doesn’t appear to be anything really functional in Mithril, in fact its component model seem to be explicitly object-orientated. Even if you have a pure-view function it doesn’t appear to guarantee any efficiency in rendering either. It’s primary claims seems to be that it’s small and fast for certain common applications.

  10. Pingback: An overview of Javascript reactive frameworks | Dinesh Ram Kali.

  11. Re: Riot – the documentation says you can replace your html, css and js processors when compiling on the server. I can’t see why this couldn’t be on the client so you can use less and coffeescript if css and javascript are not to your liking. It makes for a language agnostic system – pretty rare.

  12. Pingback: Javascript Weekly No.236 | ENUE

Leave a reply to Paul Marrington Cancel reply