Comments:"We've Open-sourced Rendr - Airbnb Engineering"
URL:http://nerds.airbnb.com/weve-open-sourced-rendr
We first introduced Rendr, our library for running Backbone.js apps seamlessly on both the client and the server, in a blog post a few months ago. We originally built Rendr to power our mobile web app, and in the post we explained our approach and showed some sample code.
We’ve been blown away by the response from the community. With 80,000 hits to the original blog post and a constant stream of questions and comments on Twitter, it quickly became clear that we’d found ourselves in the middle of a JavaScript Zeitgeist. Many developers shared the same pain points with the traditional client-side MVC approach: poor pageload performance, lack of SEO, duplication of application logic, and context switching between languages.
The number one question we received went something like this: “When will u release Rendr???”
Server-side Backbone at HTML5DevConf
A few weeks ago at HTML5DevConf I got the chance to speak on Rendr. We’ll post the video of the talk once it’s available. The conference was great: there were phenomenal speakers and many useful tips on how to build modern, maintainable JavaScript apps. Slides are below.
What’s important, though, is that we all arrived at this approach after struggling with the drawbacks of a traditional client-side Backbone app. There’s an opportunity here to combine our efforts and work towards a library that we can all use and extend to fit our needs.
If you missed HTML5DevConf, don't worry; there will be more opportunities to learn about Rendr. I'll be showing it off at NodePhilly April 23, and at the SF Node.js meetup at Airbnb HQ April 30. We will also be releasing some video tutorials, so keep an eye out.
Design Goals
Here are the simple design goals which are guiding Rendr’s development.
Write application logic agnostic to environment.
Indicating what data to fetch, which template to render, which route to match, how to transform a model’s data -- this logic can and should be abstracted from specific implementation details as much as possible.
Library, not a framework.
In true Backbone style, Rendr strives to be a library as opposed to a framework. A small collection of base classes which can be built upon is easier to adopt and maintain than a batteries-included web framework. Solve the problem at hand without imposing unneeded structure on the application.
Minimize code like if (server) {...} else {...}.
If your application has a bunch of conditions that look like this, then it means you’re doing something wrong. It’s a sign of a leaky abstraction. Of course, sometimes it’s necessary to know which environment you’re in, but that logic should be consolidated and abstracted away as much as possible. Which leads us to...
Hide complexity in the library.
There are a few really tricky problems that need to be tackled to achieve these other goals. The complexity of the solutions should be hidden in the library, keeping the application code clean, but remain accessible when it’s time to override core behaviors.
Talk to a RESTful API.
Backbone is great at integrating with a RESTful API. Let’s follow that convention, keeping the data source separate from Rendr itself. It should be possible to write adapters for different data sources, such as Mongo, CouchDB, Postgres, or Riak, but the library shouldn’t impose structure on your model layer.
No server-side DOM.
We prefer string-based templating over using a DOM on the server because DOM implementations are slow, and, well, because it feels hacky. You shouldn’t need a DOM to render HTML. (However, I’m curious how this requirement will change once WebComponents become commonplace.)
Simple Express middleware.
Express is the de facto Node.js web server. Rendr should fit with Express convention, exposing a few simple middleware. A nice effect of this is that you can tack Rendr routes onto any existing Express app, or have Rendr and non-Rendr content served from the same codebase as necessary.
The Evolution of Rendr
We would love to see Rendr evolve to become even more modular, pulling out components like the routing, templating, and view classes into separate modules, leaving the minimal set of glue required to sanely build a Backbone app that runs on the client and server. With a bit of work, it may even be possible to decouple Rendr from Backbone itself, allowing it to work with other client-side MVC libraries.
While you can easily use the code we’ve released to build a production-quality app (if you don’t mind getting your hands a bit dirty), our intention for Rendr isn’t necessarily for it to be the next [Rails, Meteor, Ember, Backbone]. Instead, we want to explore the problem of isomorphic JavaScript applications and stimulate discussion in the community.
To that end, we’ve been talking with Matt Eernisse, who maintains the Geddy project, the first and most complete web framework for Node.js. Geddy is more of a Rails-style server-side MVC framework, but Matt shares our vision for JavaScript apps that can run on both sides. We’re looking at what it would take to allow Geddy to take advantage of Rendr’s approach.
The Bigger Questions
What primitives and abstractions do we need to build applications that can seamlessly render views, route requests, and fetch data in both environments? Which of these abstractions are leaky? How far can we follow the road of environment-agnostic application code? At what point does the added complexity outweigh the benefits?
These are questions for the community to answer. We're super excited to see where Rendr and similar projects are a year from now, or two years. I expect we'll see an explosion of libraries and frameworks that address this need, and do so in radically different ways. I've just registered to speak at BackboneConf in August, and I wouldn't be suprised if there is a whole track dedicated to server-side Backbone.
Open Source at Airbnb
Rendr comes hot on the heels of the announcement of Chronos, the open source replacement for cron built by our data-infrastructure team.
We’ve also released a few JavaScript projects that are borne out of our efforts building web apps here at Airbnb.
Infinity.js is a small library for managing infinite scroll. It’s like UITableView for the web.
Polyglot.js is a browser- and Node.js-compatible library for handling internationalization. The secret-sauce of Polyglot.js is its handling of pluralization rules for non-English languages. For example, Chinese and Korean have just a single form, whereas Russian, Czech, and Polish have three forms.
We’ve got a few more exciting open source projects coming through the pipeline, so keep an eye out! Follow @AirbnbNerds and @rendrjs for updates. Also check out our AirbnbNerds Facebook page.
We're hiring
As always, we’re hiring talented engineers to work all over our stack: frontend, backend, search, trust & safety, machine learning, data-infrastructure, analytics -- you name it.