Phoenix’s LiveView: Client-Side Elixir At Last?

Well, not exactly. But what they have done is pretty freaking amazing, so read on.

In his keynote at ElixirConf last week, Chris McCord announced a new feature for the Phoenix web framework that caused many jaws to hit the floor, and had the hall buzzing when the talk was over.

The new feature, tentatively called “LiveView”, allows developers to add dynamic, client-side interactions to web pages, using code that runs in Elixir on the server.

Wait…what?

If that doesn’t immediately make sense, let’s take a step back and consider the problem.

Think of a registration form on a web page. We want to provide immediate feedback to our users when the information they’re providing is missing or incorrect. We don’t want them to have to fill out the entire form, submit it to the server, then wait for a complete page re-render to discover they made an error. We’d like to provide feedback right away.

Nowadays to do that, we turn to JavaScript. And for many developers, this quickly turns into a bewildering array of questions: should we use a framework for this? If so, which one? How should we bundle up the JavaScript: webpack, or some other tool? And everyone is saying we should be using ES6, so how do we set that up?

That seems like an awful lot of work just to be able to say “Email address is required.”

And even if we do all that work, we can’t rely solely on client-side validation to maintain data integrity. So we have to duplicate the validation logic on the server to protect against an attacker sneaking in bad data.

To work around that, we’re told to put the whole app logic into the front end, and simply have the back end expose an API. But not everyone is going to want to do that. For those of us who love Elixir, we’d like to be spending more time in Elixir, not less.

Of course there are some apps that need, or would greatly benefit from, a front end implemented completely in JavaScript. But that’s not every app. Many (possibly most) work well with pages rendered on the server, with realtime interaction added where it makes sense.

For these apps, LiveView looks like it would be a perfect fit. In our experience at Infinite Red, just about every web app we’ve built that used Ember or React could instead have used LiveView, and it might have saved a mountain of work.

So What Is It Exactly?

The project hasn’t been released yet, so we don’t have any code to look at, other than what Chris showed in the presentation. But as near as I can tell, a LiveView is lot like a React component running in a GenServer — it even has a render function! And with the EEx sigil (which I didn’t know was a thing) the code feels a lot like JSX:

Server-side clock demo — the ~E sigil provides HTML-safe EEx

A LiveView has a persistent connection to the web page via Phoenix channels, and it can respond to events coming from the client, or from the server. Changing any part of the LiveView’s state triggers a call to the render function, and the LiveView pushes the updated view code down the wire to the client. LiveView uses DOM diffing, so the updates are as efficient as possible.

The demos included the classic React-style Clock app (shown above), but instead of the timer running on the client, it ran in a LiveView on the server, and pushed the updated time to the client every second.

Chris also showed the form validation example discussed earlier, but in this example, the LiveView responded to the key press events, and the server handled validation and sent error messages back down to the client.

This means that we can take the same changesets we use in our contexts and controllers to perform realtime client-side form validation. That’s pretty amazing.

Can This Actually Scale?

Time will tell, of course, but LiveView is built on solid ground. Phoenix channels have been part of the framework for a few years. And stateful processes running on a server has been OTP’s bread and butter for the past two decades. Once again, Elixir benefits greatly from all the amazing tools that Erlang and the BEAM provide.

But Is It Fast Enough?

Oh my, yes.

The Phoenix channels implementation is super efficient, and Phoenix’s template rendering is blazingly fast. With these two working together, updates on the client appeared instantaneously during the demos.

But the real “are-you-kidding-me” moment happened when Chris showed off an animation that ran at 60FPS, completely driven by the server. He set a timer in the LiveView that went off every 16ms and pushed updated div tags down to the client. It worked perfectly, and the animation was completely smooth.

Chris was quick to point out that this is not something that you’d actually want to do, but this definitely helps validate the scaling story. If you watch nothing else in this keynote, watch this section (it starts around 40:45).

So Is Phoenix Trying To Kill JavaScript?

Not at all.

Chris stated several times that there are some types of apps that LiveView won’t be good at. For things like SPAs, apps with offline support, apps that rely on native browser features, etc you’ll still want to use JavaScript.

But for apps that rely mostly on the server and just need realtime feedback for certain interactions, LiveView presents an option we didn’t have before. We’ll be able to provide users with a rich, responsive experience, without having to split our logic into two different platforms. I can only imagine that this will make code easier to write, easier to reason about, and much easier to test.

Can I Start Using This Now?

Nope. Nothing is publicly available yet. The Phoenix team is currently focused on getting Phoenix 1.4 released, so we probably won’t see anything until sometime after that.

Currently, the plan is that LiveView will not be part of the Phoenix core. It will be a separate package and have separate versioning. The name and implementation are all subject to change, so it could end up looking very different than what I’ve described here.

In the meantime, you should definitely check out Chris’ keynote. My descriptions don’t do this feature justice — when you see it in action, you’ll likely be as excited as I am to start putting it to work.

[UPDATE]: Some readers correctly pointed out that LiveView is very close to Drab, which is already quite mature, but takes a slightly different approach. There’s a great discussion of both these libraries on ElixirForum, which includes José Valim and Tomek Gryszkiewicz (the creator of Drab).

Need help with your Phoenix project? Infinite Red has three years of production Elixir experience. Go to https://infinite.red/elixir-phoenix to learn more.