Lots of people have asked what the difference is between Ractive and other libraries and frameworks. It's long been my intention to write a series of articles attempting to answer, but I've always put it off because a) I didn't have anywhere to post the articles, and b) I didn't feel qualified to compare Ractive to libraries that I'm not particularly familiar with.
Now that I've got round to setting up this blog, a) is no longer an issue. As for b)... well, if I get stuff wrong, people will correct me – this is the Internet, after all. And I'll edit these posts as necessary to keep them accurate.
But the question I've had more frequently – and most recently – is how Ractive compares to Angular. So I'm going to start there.
What is Angular?
You're kidding, right? Angular is a wildly successful project. Its GitHub repo has 18,579 stargazers (at the time of writing) – almost ten times Ractive's 1,950. Their twitter account has 28,629 followers, and there are hundreds if not thousands of Angular apps in the wild. Most days, an article or video or tutorial about Angular will show up on the Hacker News front page if not on dozens of other front end blogs.
It is, by any measure, an impressive showing. And it's built and maintained by the geniuses at Google, several of whom work on it full time. Ractive, by contrast, has one core contributor – yours truly (though it has an excellent community which has made it immeasurably better) – and is the product of unpaid evenings and weekends. Given a choice between Angular and Ractive for a large production application, most developers would probably be wise to select Angular.
So why bother with Ractive?
Ractive, on the other hand, is designed to be as simple as possible, but no simpler. That's because of its heritage: it was created in the newsroom of theguardian.com for building interactive news applications. These apps have to be built in a very short space of time and work reliably across different environments – there's no time for prototyping etc. Just build it and ship it. You can't spend long optimising things, so the library has to make smart decisions for you.
@dmitrigrabov Simplest binding framework I've ever used is new: @RactiveJS from the Guardian. 1. have object 2. have template Done.— Mike MacCana (@mikemaccana) December 12, 2013
First piece of code that actually makes sense to my design-oriented brain: @RactiveJS - still on lesson 5, though— K. Ant. (@konstantinosant) November 27, 2013
Don't try explaining to a hacker-journalist that they need to call
$scope.digest() or that, having just got their head around minification, they need to perform some elaborate maneouvres to prevent the dependency injection from breaking – trust me, they won't care!
Enough with the sales pitch. What do they have in common?
Well, they're both largely concerned with eliminating ad-hoc DOM manipulation from the list of things developers have to worry about, by doing what's called data binding – modifying the page as data (your model, in MVC jargon) changes. Both libraries also offer two-way data binding, so that user interactions with the page update the model as necessary.
Angular wasn't the first framework to offer data binding, but it arguably did it better than anyone had before, with a concise syntax based on the Mustache templating language. Ractive also uses Mustache, since it is easy to read and write, is widely used, and comes with a formal test suite against which implementations like Ractive can check compliance.
They also share philosophical underpinnings. From angularjs.org:
Finally, both Angular and Ractive believe that your model should take the form of POJOs. Loading data from a server without having to convert it to some kind of
Collection object before you can use it is a liberating feeling. (That said, some apps benefit from the more rigorous approach, and Ractive fully supports that via adaptors – e.g. Backbone.)
And where do they differ?
Firstly, Angular isn't just about your user interface – it has opinions on routing, validation, server communication, testing, and so on. In other words it's a framework rather than a library.
Ractive only really cares about UI. Use any router/backend/whatever you want – that's your responsibility.
In some situations the framework is exactly what you need – a consistent, opinionated foundation on which to build your app. In other situations, it's a straitjacket. Personally I prefer building apps in a more modular fashion, but that's probably because of the type of app I build for a living. YMMV.
Secondly, they have very different approaches to data binding. Angular uses 'dirty checking', whereby properties of the model are checked on every
$scope.digest(), which is called automatically most of the time. Ractive uses a dependency tracking mechanism instead. When you call
ractive.set('foo', 'bar'), all the dependants of
foo are notified (if its value changed). The same principle applies when dealing with complex expressions, which means you don't have to constantly worry about whether your computed properties will cause performance issues.
Miško Hevery, the father of Angular, wrote this Stack Overflow post defending dirty checking, containing this zinger when comparing it to dependency tracking as seen in Knockout.js:
KO dependency tracking is a clever feature for a problem which angular does not have.
True, but Angular's
$digest loop is a clever solution for a problem that no other library has! In any case, Pete Hunt of React.js fame takes issue with the notion that Angular's dirty checking is fast enough.
A final important difference is in how your app is rendered. Traditional templating engines compile a string template to a function that, given some data, returns another string (which typically is
innerHTML'd into the page). Angular (and also Knockout) work by traversing the DOM, reading attributes, and setting up bindings accordingly. Aside from the FOUC that you then have to work around, this means that your page is peppered with non-validating gubbins like
Ractive takes a different approach. Your template lives as a string, and is parsed (on the server, if needs be – Ractive is isomorphic) into a tree-like structure that can be transported as JSON. From there, Ractive constructs a lightweight parallel DOM containing all the information it needs to construct the real DOM and set up data-binding etc. In my view, this is a more hygienic approach. Parsing the template before the browser has a chance to has many benefits, even if some people do question the sanity of doing so:
This is both brilliant & ridiculous at the same time: “Introducing Ractive.js: next-generation DOM manipulation” http://t.co/17uHMKZFCQ— Rev Dan Catt (@revdancatt) July 25, 2013
Honestly, just try it
This was a long post – if you made it this far, I salute you. But if you really want to know the differences between Angular and Ractive, you should just try them both. Ractive has a 60-second setup guide and a set of interactive tutorials (with more coming soon), and Angular has learning resources of its own.
Ractive's development has been very community-driven – there is no ivory tower master plan, just hard-won real-life experience distilled into feature requests. It tastes of delicious dogfood. So if it doesn't have a feature you need, there's a very real chance it could do soon – just come on over to GitHub and raise an issue.