How to make universal JavaScript applications — Part 1

A taste of what is possible.

You’ve probably heard the terms “Server Side Rendering” or “Progressive Enhancement” floating around before and perhaps even got excited about them. This is especially true if you are in the React scene. Otherwise I highly recommend checking out this great article from StrongLoop to get you up to speed.

However, if you’re anything like me, shortly after embarking down the glorious trail of server side rendering you hit a wall. Turns out that while JavaScript “can” be universal many JavaScript api’s certainly are not.

Let me show you what I mean — Lets compare an http request in node to one in the browser.

An example http request using node’s http module.

An example http request using XMLHttpRequest.

Stuff like this can quickly add up in universal apps, eventually leaving you in a scenario where you are writing the code twice anyways. You may even be tempted to go back to PHP or LanguageX+ Jquery. This may have been a huge problem a few years ago but thanks to some hard work by the community the majority of these api’s have been smoothed over. Fast forward to today and writing universal JavaScript has become easier than ever.

Lets take a look at a modern, universal, http library — Isomorphic Fetch

An example http request using Isomorphic Fetch.

Now this is beautiful and it will get even better once async functions gain more market share. Pair it with Isomorphic FormData and you’re in business. The best part though is that both apis work seamlessly in the server or browser thanks to the “browser” field in your package.json and modern JavaScript bundlers such as Browserify, Webpack and Rollup. Even libraries for things with wildly different implementations such as HTTP and XHR can now be made universal!

This technique allows libraries authors to build entirely different implementations of their library for different environments (server/browser) while keeping the api mostly intact. In this case it allows you to reuse everything you learned about the fetch api in the browser again in the server. Nowadays pretty much anything can be made universal, even a database! These libraries bring us closer to true universal JavaScript and its no longer limited to shared utilities such as Lodash. You can share pretty much anything.

Alright, what else is out there?

Well there are many great frameworks out there that help you take this further but React was one of the first, and probably something you have already seen. The beauty of React is that it abstracts away HTML into JSX which allows you to render the JSX differently depending on the environment. In the browser you want to update the existing dom, and in the server you just want to send out a string of html. Luckily with react you can do both of these tasks with the same api.

Take a look at the above JSX. Notice how lines 1–10 are the same, regardless of rendering on the server or in the browser; this is great! However quickly you notice the muck after line 10 — the apis for building the DOM are shared, but rendering sure isn’t. But it get’s worse… After hacking the above approach together you’ll realize the next step is often just as ugly — routing!

Isomorphic routing has actually come a long way since the beginnings of React. In fact you have to look no further than react-router itself. If you have never seen isomorphic routing with react-router I recommend taking a look at this excellent article by Claudio Savino. Honestly, the api is pretty good. But I know we can take it further. The plan for this multi part journy is to take a look at a framework that gets rid of all the magic non-universal apis like match and RouterContext and to take a look at what’s possible in this space.

So it begins.

This series of articles will show you exactly what is possible with universal JavaScript today. We’ll first dig deep into routing where I will primarily focus on Rill and some of it’s competitors. Later we’ll touch on wilder universal things being done today including databases (offline apps are pretty cool!), File manipulation and tons of Progressive Enhancement.

Ultimately I believe universal JavaScript is the now and it is my goal to show you all how far we have come. To get up to speed on Rill you can take a look at my first article ever on Isomorphic JavaScript — there’s a lot more coming!