Expo has been around for a few years, and it has really matured over time. We first attempted to use Expo when my team started writing React Native apps some years ago, but back then it was still very young and couldn't fulfil our needs. A lot has changed since then. I'll walk you through the journey that took us back where we started: Expo.
About 3 years ago, my team had an outsourced Cordova mobile app that was getting outdated and required too much effort to be updated. As the development team was growing, we decided to take over the mobile app and to build it from scratch in React Native.
At this point, React Native was in version 0.55 and there was already the possibility to create a new project using Expo. But Expo was still limited and we needed libraries that it didn't yet provide. Because of this, we ejected from Expo. That meant that we would need to keep both iOs and Android up and running separately.
We successfully launched the first production release in January 2019 but there was still a lot to do.
We had a lot of struggles with our workflow.
Setting up the app had a lot of steps and required installing Xcode, Android Studio, certain Java versions and SDKs, having the right certificates and profiles, and all that jazz. Our README file was gigantic and no one outside the team was willing to set up the project to contribute!
Keeping our iOs and Android apps happy at all times proved to be quite a challenge! Installing new libraries was time-consuming and didn't always work right away for both platforms, even if we followed the setup guides down to a T. Once we got to React Native version 0.60, adding new libraries was, luckily, easier, but it could still get painful at times.
Talking about versions, React Native releases new versions very often and with our ejected project it was quite a task keeping up with them, but we didn't want to stay behind! So every now and then we would reserve a few days (sometimes a full week) to migrate React Native and all libraries to the newest versions.
Another huge downside of this workflow was the time to production, for every new release we would need to go through the apps stores approval which, if everything went well, could take at least 2 days to accomplish. Not to mention that we had to manually handle the build! Because of this, hotfixes were a big problem. We would usually make monthly releases with a big stack of changes, so we could avoid the release process as much as possible, which wasn't always in the best interest of our users...
When Expo 38 was released, it had everything we needed to run our app, and we decided it was about time to go to the bright side and migrate back to it!
Since our app was quite big, we decided to start with a clean slate and progressively add content. For that, we recloned our project and created a new branch where we deleted everything and initialised an Expo managed workflow.
This allowed us to keep the old version and the migration running in parallel. This way we could keep maintaining the old version and use it for reference along with the migration! Like this, we didn't need to go back and forth in branches and deal with consequences of that (for example, ignored files in one that get transported to the other).
We started by setting up the outer shell of the app, adding React Navigation and fonts, making sure it would build and look like it did before. We also prepared the app to run in the different environments we previously had (development, staging, acceptance and production).
After this, we mapped which libraries needed to be replaced with Expo supported libraries, for example, we would need to replace React Native Firebase with Expo Notifications. Only at this point, we started adding back our source folder. To have better control over the replacement of libraries, we commented out all the components using incompatible libraries, so we could replace and refactor them one by one.
Although this was time-consuming, we believe it paid off. Our app is quite extensive and had too many libraries, this way we could progressively migrate and it made it easier to understand where errors were coming from.
One of the things that were harder to migrate were the push notifications, we had remote notifications working with React Native Firebase and switching to Expo Notifications was confusing in the beginning. It was a quite different mindset, and our backend colleagues also needed to change the way they were sending remote push notifications. But we are pretty happy with the outcome now.
A few months after the migration we can say that Expo improved our overall development process. We are glad the native build maintenance nightmare is over, and that we were able to automate most of our publishing and release processes.
Expo allows us to manage app builds and certificates painlessly. Certificates can be automatically handled and get stored in the Expo user data, which comes in handy when setting up the project on a different machine! Also, we can rely on Expo for handling and managing specific certificates. For example, as we are using Expo’s Notification service, we didn't need to worry that iOs required a certificate service update for push notifications. Expo took care of that for us!
We are thrilled we could automate our releases due to Expo's Over The Air (OTA) updates. We no longer need to manually create the builds, upload them to the stores and wait 2 or 3 days for them to be approved every time we need to make an update to the app. OTA updates allow us to now make smaller and more frequent releases, a great benefit for our users. In the past 4 months, we did 36 small releases (features and bug fixes), which we would never accomplish if it wasn't for OTA.
Previously, our iOs testers would get the app from Test Flight while Android testers would get an always changing Internal App Sharing link. Now, as Expo CLI app centralises all our app environments for both iOs and Android, our testers and stakeholders can access them the same way, no matter the kind of device!
One of the few downsides that we've encountered so far is that the app bundle size increased substantially. At the end of 2020, Expo announced Expo Application Services (EAS), which among other things builds smaller binaries that include only the code the application needs, resulting in smaller bundle sizes! We are looking forward to EAS to be available and stable for managed workflows!
The overall experience really pays off the effort of the migration, so much that we've since migrated all the other mobile apps we develop in house to Expo!