Spotlight: Peter Ullrich (Author) Interview and AMA!


Author Spotlight:
Peter Ullrich (@PJUllrich)

Data is at the core of every business, but it is useless if nobody can access and analyze it. We talked with Peter Ullrich, author of Building Table Views with Phoenix LiveView, about how Phoenix LiveView turns the normal task of presenting data into a rugged, scalable, reliable process.

This is also an AMA. Everyone commenting or asking a question will automatically be entered into our drawing to win a copy of Peter’s ebook!


Please introduce yourself.

My name is Peter Ullrich. I am a German developer living in the Netherlands. I’m the author of the book Building Table Views with Phoenix LiveView. I currently work for as a senior software engineer. I’ve been working with Elixir for the last four years. I love it. I want to use it for centuries to come. I love sharing my knowledge about it and what I’m learning and to contribute to the community as well.

Could you start off by introducing the world of Elixir?

Well, Elixir’s not that young language anymore, but it still feels very young. It is a language built by a very famous Ruby developer, José Valim. He used Ruby for a long time, and then decided that he needed a new language. The language had to be approachable as Ruby, as easy to read and write as Ruby. But it had to be one that scaled better, that handled concurrency better, and that didn’t come with all the magic that Ruby and especially Ruby on Rails comes with.

He decided to create a new language called Elixir, and he didn’t want to start completely from scratch. He wanted to build on the shoulders of giants, so he decided to use Erlang as its foundation—especially the virtual machine of Erlang, which is called the BEAM, as a foundation for the new language called Elixir. That’s why, even though Elixir is quite a young language, it comes with all the benefits of the languages that have been around for 25 years.

Elixir is battle tested. It scales really nicely. The virtual machine itself is very much bug free. It is very stable. It has amazing features that other languages try to mimic. But because they’re conceptualized differently, they aren’t able to replicate the same success.

Elixir is battle tested. It scales really nicely. The virtual machine itself is very much bug free. It is very stable. It has amazing features that other languages try to mimic. But because they’re conceptualized differently, they aren’t able to replicate the same success.

It is a very fun language to learn. It is a very easy language to write and read. It’s mostly senior developers in that community because they’ve switched from another language.

What I’m trying to do with my book is to make the language, Elixir, more approachable and easier to pick up, so that has also been the focus of my writing. I hope that it is useful to people from all knowledge levels, so to say.

What is Phoenix LiveView?

Phoenix LiveView is an extension of the web framework Phoenix. If you know Ruby, you know Rails, which is the web framework that everybody uses. There are others, but Rails is the big one, the same goes for Elixir. You have Elixir the language and then you have a web framework called Phoenix that is really stable, really well written. But it doesn’t offer interactive or reactive features.

If you have a static website, for example, you can nicely use Phoenix to render a static HTML, but as soon as you want to add some reactivity to your website. That means that, if a user clicks a button, that button should do something in the back end. It might update a record in the database. In other languages, you usually have to reach for a reactive framework like Vue.js or React itself or, nowadays, people have Svelte. Then you also have Angular.

There are single-page application frameworks out there that make it easy for you to add all these things really well so you create a good UX for your website. When a user clicks a button, something should be shown in response. Also, if something happens in the back end, in the database, you want to notify your user about it, and that can be difficult to set up with a pure web framework like Phoenix or Rails.

That’s why Chris McCord, especially, and other Elixir contributors decided that they needed to extend the Phoenix framework with a new library. This is called Phoenix LiveView. It offers these reactive components. Whenever something happens in the database, it is trivial to update the UI in the browser to show that update to the user. When a user clicks a button or interacts with your website, it is also now also trivial in Elixir to handle that button click, to handle that action, and to change something in the database, for example, or to notify somebody else and so on.

Whenever something happens in the database, [LiveView makes it] trivial to update the UI in the browser to show that update to the user. When a user clicks a button or interacts with your website, it is also now trivial in Elixir to handle that button click, to handle that action, and to change something in the database.

Using Phoenix LiveView, it has now become easy to add these interactive features to your websites. Previously, either you wrote it yourself in JavaScript or you would have to use a library like React or Vue.js or Svelte or Angular to add that reactivity to your website. That is a giant thing to reach out to. To add React to your website, completely, it can be an overkill, depending on the complexity of your website.

Phoenix LiveView hits this nice spot. It’s the spot between having a completely static website and only using Phoenix and the spot where you need a very feature-rich, complex website with a lot of state changes, a lot of user interaction, and a huge code base. If you want to have a website that is up to medium sized and that you maybe want to maintain as an Elixir developer, as a back-end engineer especially, then the LiveView framework hits this sweet spot. It’s where you have a relatively complex website and you want to add reactivity, but you don’t want to reach for these complicated frameworks like React.

Phoenix LiveView hits this nice spot. It’s the spot between having a completely static website and only using Phoenix and the spot where you need a very feature-rich, complex website with a lot of state changes, a lot of user interaction, and a huge code base.

Phoenix LiveView has been around now for maybe four years. I still remember, in my very first job, I used the very first versions of LiveView. I used them in production already. It was already an amazing library, just the feature set was limited, so I couldn’t do the things I wanted to do.

Over the last three years, LiveView has become this incredibly stable, incredibly useful and feature-rich library that now also changes how the Phoenix framework looks like. Especially now with Phoenix 1.7. With the new Phoenix 1.7, you’d see that the lessons learned from Phoenix LiveView will also now downstream, interact, and influence what the Phoenix framework itself looks like.

Over the last three years or so, LiveView has become this incredibly stable, incredibly useful and feature-rich library that now also changes what the Phoenix framework looks like.

Now you have this whole package with a very stable web framework. You can easily add this reactive feature set to it.

Is Phoenix LiveView ready for production use?

Nowadays, just go directly for Phoenix LiveView. It has grown a lot. It’s a great framework. I will say the beginning step is a little challenging for newer developers. That’s why I’m trying to make that step a little bit easier with my book. I took a very simple use case—building tables in LiveView—and then explained it from beginning to end.

Even if you haven’t used LiveView before, you hit the point of “I can just do this set of things.” I help you have a table you can filter or sort or paginate, for example, because I always say that 50 percent of the work is building tables and the other 50 percent is building forms. This book is about the first 50 percent. If you read the book, then at least you have already 50 percent of your job explained to you, so I hope that makes the start into Phoenix LiveView a little bit easier.

Why do devs build so many tables?

Yeah. I think it is just a fundamental law. We rely so much on data. We have so much data and there’s so much value in the data. For example, some is business intelligence, where you look at that data and you try to infer how the company is doing and where they’re missing opportunities and so on, so there’s so much value in this data.

I think, over the last decade, we have become better and better at aggregating that data, automatically processing that data, but, eventually, it all comes down to making it useful to the end user.

[W]e have become better and better at aggregating that data, automatically processing that data, but, eventually, it all comes down to making it useful to the end user.

For whatever reason, the table view is probably still the most predominant visualization of that data. I think it also shows that we humans are really good at seeing patterns. If we just have access to the data in a readable form, we will find the patterns in there. That’s why table views are really useful for just giving the end user access to data. Just present it on the website and make it easy to use with filtering and sorting and pagination so that the end user can do whatever they need to do.

I think that’s the beauty of this, because maybe the biggest problem with all the data that we have aggregated now is that it’s hard to give access to it. Not only because it’s a lot of data, but also because it just takes work and it takes time. That means money for companies to create websites and dashboards and everything to give the people, the specialists, access to the data.

These are the problems. If you have a lot of data not seen by the user, they could be really valuable. If users just had some access to it with some basic features to sort it and so on. That’s the fundamental problem that you can simply solve by creating a table view quickly and adding a little bit of functionality that you might use or need for that use case. Then, all of a sudden, you make the data available to the end user, the specialists, and they can use it to add value to the company.

That’s why I think knowing about table views and knowing how to build them quickly is a really, really valuable skill for engineers. It sounds boring, and, honestly, it isn’t glamorous. After you’ve built your hundredth table, you can do it while you sleep, but it adds a lot of value to the company.

[K]nowing about table views and knowing how to build them quickly is a really, really valuable skill for engineers. It sounds boring, and, honestly, it isn’t glamorous…but it adds a lot of value to the company.

How does it add value?

Over your career, you will be asked a lot of times to build tables and forms. I think that’s why it’s important to know how to do it quickly and well. That’s why it’s really valuable to businesses to just add them.

That’s why I always say that, the book I wrote, it’s not really aimed at senior experts, senior engineers, the most experienced ones. It’s also not quite aimed at new beginners like the juniors with a couple of months experience. It is rather aimed at people with one to two to three years of experience.

Those people, they have overcome the initial hurdle with Elixir to understand the language. They have to get the concept and now they are tasks by their employers to build these things, to build tables most of the time. It’s just one of these things where it’s something you need to do almost every day. If you do that almost every day, then you should know how to do it quickly. My book gets you there quickly.

I think, also, it can help you jump that gap between junior and senior quite well because, if you do the thing that everybody asks you to do every day, if you do that thing well and fast, they will also think that you’re really experienced and a great engineer. It’s good for everybody.

You don’t waste a lot of time, the company gets the business value, and you even have a higher standing with your managers because you can deliver something quickly and fast and well. That’s also why I wrote the book, to help you to bridge the gap, and I hope that’s why it’s useful.

[With my book, you] don’t waste a lot of time, the company gets the business value, and you even have a higher standing with your managers because you can deliver something quickly and fast and well.

How important is it when working with Phoenix LiveView to understand the architecture, performance, and the responsibilities of each of the stages for building interactive features?

I think it’s really important, and it’s not only important for table views and working with LiveView, but it’s important to write any code in a slightly larger code base. If you don’t structure your code base well, you yourself will run into problems in the future where you don’t understand why you put that code there and why it lives there and not somewhere else. Other people who work with you, they won’t understand why you have a query inside the LiveView instead of in a context.

If you have a predefined structure that everybody, every engineer in the team, and maybe the company even adheres to and obeys by, then it’s easier for us to understand the code of others and to understand your own code again in the future. You won’t wonder why something is there where it shouldn’t be, but you know, “Oh, a query lives in the context,” for example, the Phoenix context, so that makes sense, and that’s also the place where you would go looking for it, right?

It makes it easier for you and others to read and understand the code, and it also helps to separate these things. Right now, you might be using Phoenix LiveView, but, a year or two down the line, you might realize, “Hey, we don’t really need all of that reactivity. We want to get rid of LiveView” for whatever reason.

In that case, you don’t have to move and rewrite all your queries from the LiveView and move them into the context. No. You can just get rid of the LiveView layer, replace it with a static Phoenix layer or something else and reuse the same queries and everything else. That way, you separate the things that change a lot, like the LiveView, from the things that don’t change that much, which are database queries usually and database schema and so on.

If you think about extending your system, right now you might only have a website with the LiveView, but in a year two down the line, you might think about adding an app, for example, for iOS and Android, and that app should show the same data as the website, but on the smartphone, in the app. If you have your queries in the LiveView, how do you do that? When the app calls your server, how would you find that query in the LiveView and then fetch the data and you want to show the exact same data, not different data, in the website and the app?

That’s why you need to move the query to a place like the context where it is reusable for other devices and context and so on. It’s just one example of having a good code structure. With that, I also mean software design where it is clear to you and clear to everybody in the team and the company why certain things are in the places they are, and then, also, you need to think about requirements. Do I maybe need to reuse that query? Yes. Well, then move it outside of the things that change a lot, like the LiveView and the templates and so on.

It’s not that much about performance because, eventually, it all gets compiled and you might have a code, a function code, or more, too, but that doesn’t really make a difference. It’s more about how you work by yourself, with others, and it’s mostly, well, it all comes down to human interaction, human communication.

We need to agree on certain ways of communicating, like communication channels, certain rules in our communication, and then apply them. In this case, we agreed to have a certain structure in the code base, and that’s how we communicate with each other, so another engineer looks at the query and then understands why the query is there, and how they can use that query and so on. It’s a form of nonverbal communication, so to say. It’s implicit.

Software design, software architecture—it’s one of my most favorite topics. I think it’s really important. That’s also why, in the book, I explain a lot what the guidelines are by Phoenix, by the framework, because the Phoenix framework already comes with the Model-View-Controller layers. You have the models, the schema, so to say. You have your views, which are the LiveView, for example, and then you have some controllers, like contexts.

Is there a consistent look and feel when you use the Phoenix LiveView system? Who owns the interactivity? How does this all break down in the development?

That’s a good question. When Phoenix LiveView was first developed, it didn’t have any concept of components. It was just, in quotes, HTML templates that had some little pieces in it that were reacting to whatever happened in either the front end or in the back end. Then, over time, you see that Phoenix LiveView introduced these live components that are very similar to React, like how React is structured with modules, and they even have components there.

For example, if you have maybe even a table, if you have hundreds of tables in your website, you want to style all of them the same way. The header should look like this. The filter button should look like the sort buttons and so on. For that, you would not write the same code over and over again. You would rather create a component for that, like a table component, and then you just give data to the table component. Maybe you can add some custom actions and everything, but, in general, the wire frame, the structure, should be the same for all of them.

In the first versions of LiveView, you could simply use a template and then render the template, but the LiveView team quickly saw that you want to have more things, you want to have maybe one big LiveView, one big website, but then break up that big website into smaller components that you can reuse across different websites, so then they introduced the concept of Phoenix Live Components.

You always had two different components. You had a Phoenix component and a Phoenix Live component. The Phoenix component was a stateless component. It was not its own actor, so to say, so when a user interacted with that component, the LiveView was called and had to do something, but then you sometimes also want to have stateful components that have some logic, that can handle user actions, can maybe even fetch some data and update data and so on.

The Phoenix team then introduced the LiveComponent components, and now you have these two, the component and the live component. You see that these components already help a lot in organizing your code base and organizing your UI. Now, for your most common components, you could create these Phoenix components or live components and then you could reuse them across your website, and then there was this very, very great library called Surface. Surface used these Phoenix live components and components and added a lot of things to them that you know from React, from React components, because in React components you can expose certain attributes and you can require certain data.

You have a template, like a table, and the table should have some data or an empty array, but it should not have nothing. You need to give it something or maybe a table name, let’s say. You want to have a table name above your table, and you want to require that every table has a table name.

Well, if you had the old versions of the Phoenix components, you could just create a Phoenix component or a table that didn’t have a name, and then maybe your website would break, but that would only happen maybe later. If you don’t write a test for it, you would not see it until you deployed it, so you could not make this thing require the name. So then the Surface library came around and they added all these things that are great for developer experience, for example, attributes and then also slots in components.

The Surface library was a third-party library not integrated into LiveView that added a lot of these cool features to the components like requiring attributes and exposing which attributes a component expects and which are optional, which are required, and so on. That was the Surface library. The LiveView team worked closely with the creator of the Surface library to introduce many of these concepts into the LiveView library itself because they thought, “This is so valuable, so great. We want to use it more.” And, that happened now, and that happens continuously.

You still see that some people use the Surface library, but only most of the features that made it great, I think, I’m sorry, I’m not an expert on this particular library, but I think that a lot of people only use the LiveView library nowadays and, especially with the LiveView 0.18, which also introduced these attributes and slots to LiveView live components—a lot of these things were added to the LiveView library, so to say. Yeah. That has been a little bit the history of LiveView.

How has it developed?

I see that LiveView, the library itself, becomes more and more mature, and it tries to support bigger and bigger websites. For example, with the components, they started to add all these features and, only with these features, you as the developer can then create these giant websites with a thousand different UIs and so on because the tooling, the library itself, helps you a lot with getting the things right.

If you change something, for example, if you have your table component again and all of a sudden you have a name, and it was not required and now it is required—well, if you just made it required—if you did not have the tooling that LiveView offers you, you would have to go through all the thousand websites where the table component was used and have to find those where you don’t give the component a name. With the tooling, that will just be done for you.

You will see errors over errors, but you can just go through these errors and fix them, and after all of them are fixed, you know that you fixed them all and that the website is good to go. It’s these extra features, the extra tooling, that makes the developer experience much better nowadays. I think that’s a little bit where LiveView is headed. They worked a lot with components. I think I heard one last step that they want to do before releasing the very first 1.0 version of LiveView, which is a major version, the last thing they are considering is making forms or supporting forms in Phoenix components better.

I think that’s very exciting because, until now, building forms, especially complex forms, has always been a little bit tricky. For example, if you have multi-stage forms—say you have three different forms, but if you submit them, they should be submitted together. So think about a signup to a website where first you give an email and password and then you have to enter your name and your address and then maybe, at the third step you have to enter your credit card or bank details or something, and you don’t want the user to be fully created until the very last step, until the very last form is submitted, so to say.

All these things are not that easy yet with LiveView when it comes to forms, so I’m very excited about seeing what the LiveView team will come up with there and then to make the LiveView library like a fully rounded and mature library that we can build on.

How would LiveView render a table view?

I would start with the LiveView process, which is written in Elixir. When a user opens the website, the user makes a request to the back end, as I said, like an HTTP request, and that is handled by the LiveView, the Phoenix LiveView library, to create this process. We get the request in.

LiveView realizes, “Oh, there’s a user coming in. I need to create a process,” so the process is created and, in that process, when it starts up, when it’s mounted, so to say, you can make database calls, for example, or you fetch data from a file, but, most usually, the usual case is you make a call to the database and you ask the database, “Hey, what’s the data that I should present in this table?” In my book, I use meerkats, animals with a name and everything, so give me 10 meerkats that I want to present, and the database responds with that data.

Now, in Elixir, you have that data in a variable, and you can assign it to that connection to the socket from WebSocket. It’s called a socket. It’s just another variable where you can store data on, basically. You can assign it to that connection with the user. You fetch the data, you receive the data and you assign it to that socket. As you said, you want to have a table with a cell, so you’ll need to create an HTML template that instructs or tells the browser how to present that data.

In this case, you would use the HEEx template language, which is HTML with some sugarcoating. In there, you would have a table, HTML tag, or element, and then you would give it some cells and you would iterate through every data row you have, so for every meerkat you have, you would iterate and say, “For every one of these records, please create a table cell, and then, in the first column, you should have the name. In the second column, you should have the H,” and so on.

That’s the template basically. After fetching the data, LiveView then fetches the template and renders the template. It goes through the records, adds the table cells and so on. It sends the HTML through as a response to the HTTP request, but then, on a subsequent request, it sends the HTML through the WebSocket. Then, in the browser, you have some JavaScript that was written by the LiveView team.

This LiveView code receives that message with the HTML and recognizes, oh, that is HTML we have to put onto the browser, onto the website basically. They use a JavaScript library to merge that HTML onto the website. They say, “Hey, here, this should be shown on the website.” After the HTML is in there in the website, the browser renders it, it shows it the user, and that’s basically the end of it.

That’s the first step with the initial rendering. You make the HTTP request, fetch the data, render the template, return it to the browser, use some JavaScript to put it on the website—so to integrate it into the HTML, so to say. Now, if the user afterwards clicks the little button, for example, you send a message through the WebSocket, not through an HTTP request, and handle that action in the back end.

You might update a row, for example. You might update the name of a meerkat and, now that we updated that meerkat data, we assign the meerkat again to the socket, but the socket realizes that that data has changed, and that’s done automatically by the LiveView.

Once the WebSocket connection realizes, “Oh, this data is different,” it sends a message to the front end and just says, “Hey, at this location,” for example, in the first row, “there is a change. In this position, first row, first column, there’s a change,” and that variable that now says “Bob” should be replaced with the name “Robert,” for example. That’s all it sends, just the position and the new value, and then, in the front end, you have the JavaScript library that receives that message, and it realizes, “Okay, I have to find that position, first row, first column in my HTML template,” and then replace the content of that position with the new value.

It does that with the JavaScript library morphdom. That’s how LiveView is also special from other libraries that try to do this. In Ruby, you have the library, Hotwire, and that library tries to mimic the power of LiveView a little bit, but they do it differently. In the back end, they realize something changed, but they render the entire HTML again, or at least a part of the HTML.

They don’t only send a little message, a tiny message saying, “At this position, please put that value,” but, instead, they just say, “Hey, replace the entire row with this new row.” That’s how they do it now.

That’s why Hotwire is not as performant as LiveView now. I mean, it still serves a use case and it’s a great library, but LiveView has this advantage, that they can only send this little message and then handle that in the front end to replace only this particular value. That minimizes the message size.

How does that work with increasing performance?

LiveView increases the performance, the speed with which the message can be sent and received and handled and so on. That’s basically how it works. So you just wrap it up again, you fetch the data on the back end with Elixir. You render the template with an HTML template and you use JavaScript on the front end to show that HTML template on your website for the first render.

Then, for subsequent renders, you still fetch the data on the back end with Elixir. You might have some changed data. You only send a little message to the front end saying, “At this position, please change that value or put that value,” and then, in the front end, you have some JavaScript again that does exactly that. It finds that position in your HTML and then it only replaces that particular value.

It sounds as if having that smarter JavaScript that is local to the client not only reduces the message size, it creates greater performance for the user, but if you’re working at scale, I’d imagine the cost of the service and the overhead of creating that server would go way down. How revolutionary is that?

I would say it’s very revolutionary. You even have use cases that show how much more efficient the BEAM and Phoenix—not Phoenix LiveView yet, but Phoenix, the framework—is as compared to others. There’s a company in the US, Bleacher Report, and they make sports news, and they switched from Ruby to Elixir. I think they offer sports news, especially up-to-date sports news about games and so on, and they have a lot of users. They have a lot of users just consuming static information like the score of a game, for example, but then you have a million users all looking at the score at the same time.

They used Ruby back ends before, and they had over a hundred services running, especially at peak times, and then they slowly replaced these Ruby servers with Elixir servers, and they could reduce the hundred servers down to three. From the three servers, I think they even have one just as a backup, so to say. They have three servers so that, if one goes down, they have one backup. They only needed two servers with Elixir where they used a hundred Ruby servers before. That alone shows how well suited the Elixir language with the BEAM is for web development.

How can people follow what you’re doing and stay in touch with you?

The best way of contacting me is on Twitter at @PJUllrich. I also have a website where I blog, and it’s These two things are the best way to reach me and to stay updated.


Drop any questions or feedback you have for Peter Ullrich (@PJUllrich) into this thread. Everyone commenting or asking a question will automatically be entered into a drawing to win a copy of his Building Table Views with Phoenix LiveView ebook!

If you don’t want to wait, you can pick up your copy of Building Table Views with Phoenix LiveView today!

Don’t forget you get 35 percent off with the coupon code!


Corresponding tweet for this thread:

Share link for this tweet.

1 Like

Does your book identifies design patterns on how to implement advanced table features in a clean and reusable way?


Another great Spotlight! I especially liked the history and component sections - thank you!

I have some questions :blush:

  • As you’ve seen Elixir and Phoenix grow over the years, what do you think is going to be the next big thing in Elixir?
  • After LiveView 1.0 (and multi-stage forms) what do you think (or hope) we’ll see in LiveView in future?
  • After (or other than) LiveView, what else do you think or might like to see in Phoenix?

Great spotlight. Clearly explained the sweet spot where liveview really fits in. Phoenix and liveview makes the life of indie developers much easier.

Eagerly Waiting for your video course.


On Thi book you use some lib for the pagination like scrivener?


Hi, considering your experience with Elixir/Phoenix, what is lacking to Elixir and Phoenix to breakthrough and become more popular?


Does LiveView have any limitations or gotchas that new comers won’t be familiar with, and if there are any workarounds to those limitations if any?


Hey, it does to a certain extend! All features like Pagination, Filtering, and Sorting live in their own Phoenix Component. The fields that they use are hard-coded but you could easily provide them as a list or schemaless changeset when you re-use them in another template.


Hey, thank you :slight_smile: Great questions!

  1. Honestly, José would be the best person to ask this question. I have no visibility into other industries and areas of software development other than web development. However, I see that we’re pushing into the ML, Data Science space and I expect this trend to continue.
  2. I hope that we see expansion into iOS and Android through LiveViewNative and that - at one point - we’ll see offline capabilities as well. Maybe something smart where the state is kept in the browser AND in the LiveView process and they sync continuously. That’d allow offline capabilities and connection loss mitigation.
  3. Phoenix feels pretty complete already to be honest. I think the focus will be on LiveView and Phoenix will be updated to support any development there as we have seen with LiveView 0.18 and Phoenix 1.7 already.

Well wait no longer! :smiley: The video course is available here: Build an MVP with Elixir


Nope, I write the pagination functionality myself. It’s not that hard to do, really.


The technology is impressive and a strong argument by itself. However, I think we need to focus more on attracting and onboarding devs from other languages and new devs. It’s a community effort though and there isn’t a silver bullet for this. But we should look at other communities like the Python community and see how they make it easy and attractive to switch to or to start with Python. If we only focus on getting Senior Engineers from other languages into Elixir, adoption will be limited.


Absolutely. There’s no offline capability or connection loss mitigation. You need a stable internet connection to use it, which isn’t the case on e.g. mobile. That’s probably the biggest caveat over a SPA like React that can quickly switch over to an in-memory state and then sync it up with the server once the connection is re-established.