It would be an understatement to say that Relay, GraphQL, Falcorjs, and other
up-and-coming technologies have revolutionized how I think about building user
interfaces. I’ve been doing a number of experiments to explore how we can build
applications with the ideas of these tools, even without access to their
implementation.

Relay, GraphQL,
and Falcorjs all aim to
generalize a solution to data fetching and updating. The ideas of REST have been
tried, tested, and pushed to the limits. While they have numerous, well-known
benefits, they are a database/model-centric view of the world. In today’s device
landscape, the view is a much more difficult land to maintain and support for
any length of time. These approaches flip the API layer from being model-centric
to view-centric where the view dictates what data it requires and the shape that
it should be in.

Below is a brief introduction to what the first experience has entailed and some
predictions on what this means for the future.

Isomorphic Views

Sharing JavaScript between the server and client—typically referred to as
isomorphic JavaScript—has been something we in the front-end world have been
dreaming of since Node.js was first announced. As such, we primarily reserved
shared code to be the utilities of our applications.

Sure, there are a few success stories like Airbnb
with Rendr and Yahoo!
with Mojito, though these
previous efforts haven’t taken hold in the community. The fact that all of the
tools and frameworks being created have a hard dependency on the DOM hasn’t
helped, either.

At a minimum, to have isomorphic views, one needs to be able to run purely in JS,
output and update DOM structures (for the browser) and HTML strings (for the
server), and needs to interoperate with Node/iojs’s module system.

Isomorphic Data

Historically, we’ve attempted to keep the structural, presentational, and
behavioral aspects of our web UIs isolated through the arbitrary technological
separation of concerns.

The React team came on the scene with the idea of “rethinking our best
practices.” React took this approach to our UIs by marrying behavioral and view
concerns together. The React team has also been rethinking application
architecture and the MV* paradigm that is so prevalent. They have introduced
Flux, which, like MVC, is an architectural style or idea. Whilst MVC has always
been pitched to me as a way to segregate concerns to build more maintainable
applications, in practice, there always ends up being tight—and typically
unclear—coupling between the pieces. In my experience thus far, Flux embraces
this inherent coupling and offers up a way to organize responsibilities with a
directed path through your codebase. Namely, for every action that can take
place in your application, it must go through a central dispatcher which informs
your data stores of what took place. It is then up to your stores on how to
change and inform the view that something changed.

For a better introduction to Flux, I would highly recommend the following slides
by Jeremy Morrell in addition to the primary Flux documentation.

Whether you choose a verbose implementation or something that hides away some of
the boilerplate, the result is a very predictable and understandable system.

The Experiment

At Skookum, we create user personas for each client project. Historically, these
personas have lived in a shared document as unceremonious blobs of text. My
colleague Rob Luke has recently been working on a prototype for displaying these
personas in a rich and interactive environment. This is a simple application
involving a single list and detail view.

isomorphic-browser

I spent the first five hours of my experiment day building this prototype with
React. Architecturally speaking, this project uses react-resolver, react-router,
and facebook’s flux dispatcher to handle isomorphic rendering. Rendering our
HTML on both sides of the HTTP divide is fairly simple with these tools. Below
is a slightly out-dated variant of the node and web entry points we are
currently using:

gist#https://gist.github.com/iamdustan/a4cde6f780836d9df1df.js

The ideas and learnings from this and a few other projects are culminating in
our isomorphic react application generator.

Isomorphic Flux

So we’ve proven that we can write the same codebase to power client and server rendering.

Next, I wondered if I could reuse any of the code from the web implementation to create a React Native application. React Native has a strong view layer already, so I wanted to experiment on the data access and flow layer. I started a new React Native application and referenced the Flux folder from the previous project into it. It was astounding having no previous iOS experience and only needing to spend an hour and a half to have a NavigatorIOS component connected to a list and detail view. The exact same Store and Action code that was powering the server and client DOM rendering implementation was powering the native application!

gist#https://gist.github.com/iamdustan/98a8039e7fe056f61d88.js

isomorphic-mobile

The View-Driven Future

The “write once, run anywhere” dream, though appealing, is a mystical unicorn.
The two primary motivations for “running everywhere” is cost (money, time,
effort) savings through code reuse, and audience reach. Although we are able to
“write once, run a lot of places” on the web, we are forced to make numerous trade-offs to get there. React has the potential to greatly reduce the cost
associated with specific implementations for multiple platforms.

My prediction for the next major evolution in the UI engineering world is that
models will become view-centric. RESTful APIs are a great utility belt, but
carry a cost of lost flexibility. To build scalable, maintainable systems we
need to push the decisions of both data required and the shape of it out to the
edges of our system—our users devices.


Thanks to Dan Abromov, Evan Booth,
Patrick Laughlin, and Andrew Gertig for feedback on a draft of this article.