Client side layout engines: React vs FruitMachine

Facebook recently announced React, which they describe as ‘A JavaScript library for building user interfaces’. Well, I thought. We’ve got one of those too, called Fruit Machine. I’d been wondering how they compared and hadn’t got round to checking out React, but my colleague Matt Andrews spent a few hours pulling together an example component using both Fruit Machine and React, so you can see how they differ.

One of React’s code samples is a timer component that counts up in seconds from when the page was loaded. Here’s their code:

var Timer = React.createClass({
  getInitialState: function() {
    return {secondsElapsed: 0};
  },
  tick: function() {
    this.setState({secondsElapsed: this.state.secondsElapsed + 1});
  },
  componentDidMount: function() {
    this.interval = setInterval(this.tick, 1000);
  },
  componentWillUnmount: function() {
    clearInterval(this.interval);
  },
  render: function() {
    return React.DOM.div({},
      'Seconds Elapsed: ' + this.state.secondsElapsed
    );
  }
});

Now here’s the same thing as a Fruit module:

var Timer = fruitmachine.define({
  name: 'timer',
  initialize: function(options){
    this.model.set({ secondsElapsed: 0 });
    this.tick = this.tick.bind(this);
  },
  tick: function() {
    this.model.set({
      secondsElapsed: this.model.get('secondsElapsed') + 1
    });
    this.render();
  },
  setup: function(){
    this.interval = setInterval(this.tick, 1000);
  },
  teardown: function(){
    clearInterval(this.interval);
  },
  template: function(data) {
    return '<div>Seconds Elapsed: ' + data.secondsElapsed + '</div>';
  }
});

Eerily similar, no? Maybe Facebook was inspired by Fruit Machine (after all, we got there first), but more likely, it just shows that this is a pretty decent way to solve the problem, and great minds think alike. We’re graduating to a third phase in the evolution of web best practice – from intermingling of markup, style and behaviour, through a phase in which those concerns became ever more separated and encapsulated, and finally to a model where we can do that separation at a component level. Developments like Web Components show the direction the web community is moving, and frameworks like React and Fruit Machine are in fact not a lot more than polyfills for that promised behaviour to come.

There are still some significant differences though, which are worth examining. For example, React comes with a markup generator in Javascript called JSX, which is designed around the idea that to create the richness of markup that you want, you should have the power of the full programming language, rather than a simplified template engine. For Fruit Machine, we didn’t include either markup generator or template engine, so you have to bring your own, though we typically partner it with Mustache.

Another area that differs is the treatment of child views – ie. how your component can contain other components. React does this by creating child elements when the component is rendered and instantiating their components – heavy influence of custom elements and web components here. Fruit Machine takes a different approach by adding the children as a property of the parent component’s module definition, and assigning their output to slots that are specified in the parent component’s render template.

The advantage of the Fruit machine approach is that it looks like React components effectively hard code what sub-components make up a parent component. That probably wouldn’t work quite so well for us; the combination of components is never quite the same page to page, and we use components as responsive layout containers as well as individual widgets. Also, having got used to logicless templates, going back to being able to have logic in templates feels a little like a backwards step.

React’s documentation is however, hands down, prettier than ours.