From Hours to Minutes: Making older React Native Apps easy to set up

Marin Godechot
Engineering at Birdie
4 min readFeb 27, 2023
Photo by Lucas Degenhardt on Unsplash

As developers, we’ve all been there. We get excited to learn a new programming language or work on a new project, only to find ourselves stuck for hours on setting up the development environment and searching for obscure error messages online. This is especially true for React Native development, where getting your native environment set up can be a nightmare. But what if I told you that it doesn’t have to be this way?

Thanks to Expo and its tools like Expo Snack, Expo Go, and Expo Dev Client, setting up a new React Native project has become a breeze. But what if, like us at birdie, you have a massive React Native app that was created years ago that is still on older versions of React Native and Expo SDK, preventing you from playing with the new toys? Sure, you could invest the time to upgrade everything, but that would take ages, it might be better to explore other options to enhance the developer experience in the immediate term.

What makes setting up a React Native development environment so hard is that you need to have three parts configured properly: the JavaScript part, the Android native part, and the iOS native part. Each of these parts can already be a pain on its own, but the native parts are particularly challenging. For Android, you might need to have Java, Gradle, and Android Studio set up and configured, while for iOS, you need Ruby, Cocoapods, and XCode.

When we got new engineers to work on our mobile app, it was often the case that one of the pieces wasn’t installed or configured properly. The error messages we got weren’t that helpful either, so we ended up spending hours trying to figure out what was wrong. Things got even worse when engineers started using M1 MacBooks since not all required software was compatible with ARM yet.

It got to the point where making a trivial change in the app would be considered a high cost for a team if they hadn’t setup the app locally in a long time. With a quickly growing engineering team, we needed to fix this urgently.

Given that the hard part is the native side, but we very rarely make changes to the native code, why build it again and again when developing locally? Our solution was to remove the need for setting up the native environment entirely when working on the JavaScript code. By building the native parts of the dev app in advance, engineers simply need to download the pre-built dev app and set up the JavaScript side with a quick yarn install && yarn start. It now takes less than 5 minutes for a newjoiner to be able to start working on our app.

We did this by using another Expo product, EAS, which allowed us to build the native parts in advance and bypass the need for developers to set up their local environment.

EAS Build is designed to work with any React Native project, which allowed us to set it up with no changes to our app code. Using Github Actions, we now have dev apps built automatically for iOS and Android whenever we create a new native version.

Here is how we have it setup:

After following Expo’s instructions on creating an account and setting up our app, we configured EAS through the eas.json file like so:

{
"cli": {
"version": ">= 0.55.1"
},
"build": {
"dev": {
"distribution": "internal",
"android": {
"gradleCommand": ":app:assembleDebug",
"image": "ubuntu-18.04-jdk-11-ndk-r19c"
},
"ios": {
"simulator": true,
"buildConfiguration": "Debug"
},
"env": {
"ENVFILE": ".env.dev"
}
}
}
}

By specifying the exact gradle command to use for Android and build configuration to use for iOS, we made sure that it would work with our existing native dev build setup which doesn’t necessarily match Expo’s defaults.

By specifying which server image to use for Android, we make sure that the build tools on the server are compatible with our versions of Expo SDK and React Native. If you use the recommended version of React Native for your Expo SDK, you don’t have to do this as EAS will pick a compatible server for you.

To create a dev build, from our CI or from a laptop, we use eas-cli like this: eas build --profile dev --platform all --non-interactive.

Our mobile app is versioned in a SemVer format, with the implication that a native change leads to at least a minor version bump. This allows us to only build dev apps when needed by having a step in our CI that looks for version changes and calls the command above when there is a major or minor version change.

Engineers can then download the latest build from EAS and not worry about the native side of the app until the next minor version change, at which point they need to download the new build.

This solution worked for us, but you could also build a similar system with fastlane and your preferred CI service. We chose EAS due to its ease of use and setup, plus our intention to migrate other build and release processes there in the future.

Going forward, our plans include upgrading our React Native and Expo SDK versions to have access to all the latest tools and features. We also plan on using Expo Dev Client, which should make our development process even smoother.

No more hours spent trying to configure the development environment — just a quick and easy setup process so we can get back to what we do best: building delightful features for our users.

We’re hiring for a variety of roles within engineering. Come check them out here:

https://www.birdie.care/join-us#jobs-live

--

--

Marin Godechot
Engineering at Birdie

Mobile Platform Engineer at birdie. Music producer; Mechanical keyboards, watches, video games, and headphones enthusiast.