XState in the Wild

This is the full interview with Doug Lowder about how Expo uses XState.

Expo is a company that develops a suite of tools and services to simplify building, deploying, and maintaining React Native applications. Expo uses XState in the Expo Updates package, which enables remote updates of application code. Doug Lowder, who introduced XState at Expo, accepted my invitation to talk with me about Expo Updates, XState, state machines, and React Server Components.

Links:
- Expo Updates
- Doug Lowder on GitHub
- XState state machine in Expo Updates
- React Native tvOS
- Expo Router
- Evan Bacon's talk about RSC in Expo Router
- Review of Expo's XState implementation

Creators & Guests

Host
Baptiste Devessier
XState consultant
Guest
Doug Lowder
Mobile Software Developer at Expo

What is XState in the Wild?

XState in the Wild is a podcast hosted by Baptiste Devessier about how XState is used across the tech industry to solve complex problems elegantly.

Baptiste Devessier: [00:00:00] Hello Douglas thank you for joining me you are a developer at Expo and I saw that you worked with Xstate at Expo and I'm very glad you, you take the time to talk with with me about Xstate. So, let me can you talk about yourself a bit?

Doug Lowder: Oh yes, my name is Doug Louder I work at Expo, I've been a developer here for two years.

I'm been involved in the React Native community for quite a few years now. I am the the, the developer who built the React Native Apple TV port, and I maintain the React Native Tele TV repo for Apple TV and Android TV, and have been working on Expo for, for their updates feature, and now for the notifications feature.

And also support TV at Expo.

Baptiste Devessier: Great. And so I saw in the repository of Expo that Expo updates uses [00:01:00] Xstate. And you told me that it uses Xstate, but not in production. That that was to, to make it possible for developers to understand the state machine you then implemented in Kotlin. And in Swift, is it right?

Doug Lowder: That is exactly right. We decided that we needed to have a state machine because our update system manages in native code, over the air updates and it has to be very reliable. And we decided that in order to make it as reliable as possible and in order for the JS layer to have correct and updated information on the exact state of what was happening in the native code, we needed to implement a state machine inside the updates package.

So we did that. And in order to make sure that we had the right state machine. Without trying to iterate very slowly in native code, we built a model of that state machine in X state, which turned out to be a great idea [00:02:00] because X state is a beautiful way of modeling very quickly different state machines in TypeScript.

which is the language that we used and manipulating those and exercising those state machines on the web and in visual studio code. And so several developers, including the other main developer that worked on expo were able to try out these models and suggest changes. And so we were able to very rapidly iterate and come to an agreement on exactly the model that we wanted.

And just to make sure that we had a reference. We did check that model into our, into our source tree. But that's not, that's not, that model is basically a reference for the native code that's actually used in production.

Baptiste Devessier: Okay. And did you use the visual tools that Stately, the company that develops currently Expo.

To model the state machine, or did you stick with code for that?

Doug Lowder: We used both. [00:03:00] State, they, stately, we started out with stately because it's so easy. So it's just right there on the web. But in order, since we do a lot of our development on the TypeScript and JavaScript side in Visual Studio Code, it was nice to have that The plugin there that enables you to actually exercise the state machine there as well and actually edit, edit the state machine in Visual Studio Code and see the changes as they happen.

Yes,

Baptiste Devessier: that's great. And I saw that you didn't use a state machine library for Kotlin and for Swift. My question, I don't really know this native languages. How is the support for state machines in Swift, in Kotlin? Why didn't you use a state machine? Could you use a state machine? That's my, my question because when I build state machines in JavaScript, I always use XState and yes.

How is it with other languages?

Doug Lowder: Well, because we were trying to keep our [00:04:00] implementation as simple as possible and easy to maintain, we ended up basically building our own native native classes that represented as closely as possible the state machine that we ended up with in TypeScript.

So we just basically had the. A representation of the state and the context and just the sort of the bare minimum we needed to make things work the way we wanted. We were actually, the state machine that we ended up with is actually not very complicated. It only has a few states. The most of the complexity is in the context changes.

So we were, we were able to get away with not having a very complex, if we had had a more complex state machine, of course. There are native packages in both Swift and Kotlin that are designed for that, but we didn't really have to end up using those.

Baptiste Devessier: Yes. Great. Yes. Because I saw that your state machine has both transitions, states, events, and a context, and you, based on the [00:05:00] transitions you, you, you allow, you take some changes to the context.

This is the same thing with XState. We have the context and the states. And I saw that in your custom implementation, you, you really decide what's the next shape of the context needs to be based on the current state and the events you receive. This is, this is interesting I tell that because sometimes people build state machines with their, their hands without using libraries.

And the context is not something that should be implemented. I submit implementation only about states and not context to, to get more information as you did the, in your implementation. So,

Doug Lowder: and well, the, the state sort of represents it's, it's really represents in a sense, the network state.

It's the we, we have states representing what happens when we send out a request to see if an update is available. And then when we get the response to that, and then we [00:06:00] have another state transition, when we reach out to actually download that update. And then when we get the response to that as well.

And so the the context really represents whatever we're getting from the server. And so based on whatever we get from the server, we make the right changes to the context on the client. Great.

Baptiste Devessier: Maybe we can explain a bit, what's the purpose of state machine and expo updates. I did a bit of expo development.

And I'm talking about under your, your review. But I think exploit updates is to get a fresh JavaScript update from my application without downloading it from the app store. Is it right? Or.

Doug Lowder: That is correct. Yes. As long as you're only make small changes to, for example, the JavaScript bundle.

And things like that. If you make changes to native code, then you have to rebuild the app and you have to submit it to the app store. But if you're making [00:07:00] small changes that only touch JavaScript or TypeScript. And only required that the bundle be rebuilt. Then we have a system that allows that bundle to be served by the update server.

And so the we have a protocol by which the application can reliably ask for whether a new update is available. And whether, and then if that update is available, it can download and it actually can reload the JavaScript engine with the new bundle. Okay.

Baptiste Devessier: And is it something automatic or can developers choose to, to relaunch the application while the user uses it?

Doug Lowder: Both. You can actually, we actually have a JavaScript API. For really reloading the app on the fly while the, while the person is using it. And then once you have an update that's considered the latest update we have a database of those updates that exist on the client. And when the client when the application restarts it looks for whichever update is the latest [00:08:00] and is known to be the right one.

It launches that.

Baptiste Devessier: And what is this database you are talking about? Is it some SQL light or I don't know, a G zone stored in the device?

Doug Lowder: It's a SQLite database. Okay.

Baptiste Devessier: Interesting. And

Doug Lowder: Yeah, the actual the, the SQLite basically stores metadata about the about the about the updates and then the actual update assets, including the bundles live in the file system.

Baptiste Devessier: Okay. And about taking updates from the server, I heard about React server components used with Expo. And my question will be, Is it authorized by like the Apple store to get updates like this from the server? Because as far as I understand, the objective of the React server components with Expo would be to serve some screens from the server.

I don't really know how it can apply to, to native applications.[00:09:00]

Doug Lowder: The answer is very complicated to that question. It depends on the application. Essentially the, you understand, I'm, I'm not officially speaking for Apple or Google, but my understanding of what they say in their app store guidelines is that you can't. Make, if you make changes to the app that significantly changed the functionality of it, then that requires that you rebuild the app and submit it to the app store for review again.

But if you're if you're making changes, if you're using JavaScript and are making small changes, then that's okay. Again the only way you will really know what's okay is if when you. If you actually submit your app to the app store and they will tell you if it's okay or not.

Baptiste Devessier: Okay.

Doug Lowder: That's the, they're, they're, they're, Apple and Google are always the source of truth for, for things like that.

Great.

Baptiste Devessier: It's, it's great to see some improvements in the native land [00:10:00] like this. I've been using the Hey email service for a long time now, and I think their native applications relies on some kind of server side things in the iOS application and I didn't really know if it was allowed or not.

But if it's if they were doing it, I don't know.

Doug Lowder: I mean, I mean, it's it's a, it's certainly a topic of active debate. I mean, if you think about it, any application that's a web application can be updated completely on the fly. It's just, you get whatever's on the server at all times. So this is, this is really sort of the same model in that sense.

But. Thanks. You know, you have, you have to basically use good judgment and make sure that you're following all of the guidelines that Apple and Google give you from their app stores.

Baptiste Devessier: And about state machines how did you learn about state machines specifically? I've been using them, I've been discovering them thanks to XState.[00:11:00]

I didn't learn about them previously. So how did you, is it something you, you knew for a long time or something you discovered recently? State machines. I

Doug Lowder: had worked with very simple state machines in the past because a long, a long time ago I was, I worked on embedded systems, operating system work.

With Linux running on different types of embedded systems and things like that and even code that was actually running on the bare processor. And in those cases, you have to be very careful how you design your code. And sort of check all paths that the code could follow and state machines turn out to be very useful for modeling code like that and making sure that it can't break no matter what happens.

I think that the, what, what X state provides is a lot more complex and sophisticated than the sort of state machines that I was working with back then. But in terms of the basic concepts of, you know, always making sure that you follow the rules [00:12:00] and every, you know, all state, you can never be in any, you can never be in any state other than one of the states you defined.

That's a good model to have to make sure that your code doesn't break. And it was nice to see that X state had done a really good job of building that. In a modern language like TypeScript, which is very easy for for React Native developers to use. So it was, it was actually a very nice tool for us.

Baptiste Devessier: What I love with XState is that it doesn't simply allow developers to create state machines, but it follows the state charts. Recommendation, the specification is SCXML and we can build compound states, parallel states, things really more sophisticated and not necessarily useful for every project.

But yes, you, I can build anything I want, any kind of I think diagram or system I want with X state from the simple one to the more [00:13:00] complex. And yeah, this is something that we, we barely,

Doug Lowder: we barely scratched the surface of what it can do for, for our project. But it was what the nice thing about X state is that it's designed so that you can build something simple very quickly which was exactly what we needed.

Yes.

Baptiste Devessier: And what do you think about using state machines? Or more specifically, state in user code, in react native applications?

Doug Lowder: I think for I, I could see it being extremely useful for certain types of applications. And if, if I ever come across a use case that requires a state machine actually in the JavaScript bundle.

That would be the first place I'd look will be, will be X state for sure.

Baptiste Devessier: Yes. One thing I like to implement with X state in my React Native application is authentication. Because I, I know that with the most modern Expo versions, there is now the Expo [00:14:00] router to use file based structure to, to define pages.

But previously I've been using React Navigation. And you had to declare authentication state or other things. And I like to use Xstate to, to control all those authentication flows that can become complex the more you add features.

Doug Lowder: Yeah I could see that being very useful particularly if you have more complex authentication setups.

So yeah, I do agree that Expo Router has done a good job of solving some of those issues. It's sort of a, it's sort of a state machine in a sense itself. Everything, the routes actually define, sort of define the state. You can never be in anything other than one of the routes that's allowed. So that's I'm, I'm still I'm actually been spending a lot of time learning how to build things with Expo Router recently in the past, in the past [00:15:00] few months.

And I'm really liking the way that it sort of makes sure that you stay with, you, you basically know exactly in all the states or the routes that the, the, the system can be in. Great.

Baptiste Devessier: And so do the React server components will be inside the XPOW router? Or is it something more agnostic is it tied to Expo Router?

Doug Lowder: That is not something that I'm actually, that's something that's still under development, to be honest. I'm, I'm going to wait and let the developers who are working on that make sure that they, they know all the answers to your questions and they, they, they will, there's some good talks actually.

Evan Bacon just came out with a good talk on, on that subject. That's a part that was part of AppJS. And I think they just released that as a YouTube video.

Baptiste Devessier: I will link to it in the description of the video. So, and I saw that you did a lot of work. About April TV [00:16:00] and react native. Can you talk about about that a bit, please?

Doug Lowder: That's been something I've been working on since 2016, 2017. And currently maintaining the, the, the repo that made that it's basically a fork of react native core. Where we've added the support for Android TV and Apple TV. It's basically some, it's mostly the same code. It's mostly iOS. The same code is on the core, about 90 percent of the Apple TV code and iOS code are in common but there are some Features that have to be added, particularly for managing how you navigate around the screen with a remote control and some other changes that happen when you move to those platforms.

And we've been maintaining that as a separate repo for the last few years. Now more recently I've made some changes at expo so that expo fully supports TV. Most of the, most of the core expo packages now support TV, [00:17:00] including the video packages, the the audio even the expo router works.

The only, the only major package that doesn't work on TV right now is the Expo dev client, I would say.

Baptiste Devessier: And what kind of application can can we port to TVs? I didn't do do that. So I, I don't really know what kind of application must go to Apple TV or Android TV.

Doug Lowder: Obviously most, most of the people who are interested in the TV platforms are interested in streaming audio and video.

But it's also good for any, anything that requires a large display. For example, I've, I've seen financial applications that do large graphics, you know, of your, of your portfolios on the TV and shopping apps, various other things. There's, there's quite a few apps out there. Okay. It's not as popular, obviously, as the phone through web but there are there are people particularly as I said, [00:18:00] the, the large streaming platforms do like to have apps running on TVs.

Baptiste Devessier: Okay.

Doug Lowder: And it's it's also, A bit complicated because in addition to the repo that I run for, for Apple TV and Android TV, there's many TV platforms where you have to build things as web apps. And so there's a large amount of effort going into making web apps that can run on these TVs.

Baptiste Devessier: Okay.

Doug Lowder: And many of those, and obviously many of those people use a expo web.

Yes.

Baptiste Devessier: That's a great use case for Expo web. So, yeah. And do those do those other kinds of TVs do use. Hold JavaScript runtimes or are they up to date and we can use recent JS features on them?

Doug Lowder: The answer is both. There's, there's many TVs that are, you know, modern where you can actually, we actually can use modern HTML and Java and JavaScript.

And there's many that are not there's many TVs out [00:19:00] there that are 10 years old or, you know, more. And supporting them gets to be a challenge, as you might imagine.

Baptiste Devessier: Okay. Yes, because you have to support all TVs that have been released 10 years ago, and that can still receive those kind of applications.

Yeah. Yes, I can understand that it's quite a bit hard to support. Yeah, exactly. Yes. And is VS Code, uh, able to run on a TV? Because I know that developers like to have big screens. Maybe we can use VSCode on the, on the TV to, to code

Doug Lowder: I don't think it does. I've never tried it. The, the most I've ever done is I have a, I have a really big screen Android TV that I have that has a bunch of different HDMI inputs. And one of them is for my for my development machine. So I can actually see all that code on the TV. And then I have another, another input that's for the Apple TV, and then it also runs [00:20:00] Android TV.

So I can, so I have to switch back and forth between all those different things.

Baptiste Devessier: Great. So, yes. Do you have something to say about safe machines? You. We, we didn't say yet, or do you think it's

Doug Lowder: good? I, I think that we had a, that was a, that was a good summary of, of where we are with updates, why we use state machines there.

And I think as you say, X state is a really good, very sophisticated package, anyone wanting to use state machines for react to react native should, should definitely try X state out, I think.

Baptiste Devessier: That's a great summary. Thank you. Where can we find your work online, Doug?

Doug Lowder: You can find me at GitHub Doug Lauder is my username.

And you can find you can find me at the React Native TV repo. And on the React Native contributors discord and the expo discord.

Baptiste Devessier: Great. [00:21:00] So thank you a lot, Doug, for your time. It was a pleasure to talk to, to talk with you and have a, have a good night because it's it's been late at your home.

Thank you.

Doug Lowder: Bye. Thank you very much. It was great.