As we all know, React Native has become very popular. Based on our existing experience, after a lot of analysis and research, we finally integrated React Native into our existing project. This article shows how we analyze and make technical decisions.
If you’d like to know more about React Native, please refer to https://reactnative.dev/
What we have is a dual app (e.g. the driver's and passenger's side of a ride-hailing app) which supports both Android and iOS, meaning we have four versions online. They are medium-sized, but six years old, have been maintained by multiple developers, and have become less maintainable now. Additionally, our team has been lacking in Android developers for a long time, resulting in a huge difference in the progress and quality of development between the two platforms.
React Native analysis
Is React Native right for our project?
First, we know that our app is not very large or complex. Also, it’s mainly based on data display, meaning that interaction logic is relatively simple and performance requirements low, and it doesn’t interact with peripherals. This makes React Native a great fit.
And we can get a lot benefits from React Native:
- Cross-platform: Maintaining React Native is much easier than native apps as you don’t have to hire separate teams for different platforms. The result is smaller teams, meaning lower costs and easier-to-manage projects.
- Faster updates: React Native allows us to update the app without app store approvals. That means your updates can bypass app stores entirely. Mobile apps often release a new version every two weeks. But waiting for approval from the app store/play market often adds several days to the process.
- Easy to Debug: Unlike native development, it doesn’t need to compile every time when debugging, and its Fast Refresh feature can make code changes take effect instantly. It allows developers to immediately see how the app is affected while it’s running. This feature saves a ton of time and makes developers happier. You can debug with Chrome or Flipper.
Are there any risks?
If we opt for a gradual migration scenario, Native and React Native will coexist for a long time. Hybrid development models complicate things and affect delivery efficiency.
If the infrastructure isn’t designed well, it may lead to a dilemma for React Native migration, resulting in failure.
Does React Native support the libraries we’ve been using? e.g. Sendbird, Analytics, etc.
Are there features in the app that aren’t supported by React Native?
We need to consider the disadvantages of React Native, such as:
Dependence on Facebook. If one day Facebook ceases support of React Native, the framework would quickly fall behind both iOS and Android. However, this is highly unlikely.
New feature delay. Google and Apple constantly update their OS with new features. The React Native team does its best to bring new functionality to the platform, but that takes time. So if you want to use fancy features like Face ID in your app, you’ll either have to create native bridges or wait until somebody in the RN community comes up with a solution.
Compatibility & debugging issues. While it may come as a surprise, React Native is still in beta. Your developers might come across various issues with package compatibility or debugging tools. If your developers aren’t proficient in React Native, this might negatively impact your development as they spend time on troubleshooting.
Is it worth migrating to React Native?
How much effort will it take?
Can we afford a failed migration?
Are React Native developers easy to recruit?
Carefully weighing the risks and benefits alleviated all our concerns and we received the company’s go-ahead to proceed.
Why not Flutter?
React Native and Flutter are often compared to each other. Four factors tipped the scale towards React Native:
React Native is based on React and JS. Flutter uses a new language named Dart. This gives React Native a lower entry threshold, making it easier for mobile and frontend developers to join;
React Native has a more mature and active community, with many third-party libraries. Inversely, Dart is younger and its community less developed.
Recruiting React Native developers is easier.
We already had React Native developers on our team.
Decisions of implementation
Now that we've decided to migrate our six-year project to React Native, what should we do? Two options here:
Greenfield: Create a new React Native project, build from scratch, and then make a new app like the existing app.
Brownfield: Integrate React Native into existing native projects and gradually replace them.
Thinking from different perspectives
From the developer's point of view, the greenfield development experience is better, more efficient. Brownfield will bring a lot of extra work, as we need to consider interactions between Native and React Native and the structure is also more complex.
With greenfield, the team doesn’t have an intuitive stage output until existing features are aligned. This cycle is also very long. If it fails, it causes huge losses. Higher risk and cost.
With brownfield, the team is prone to produce phased results, but will still move forward. The overall risk is small.
The project is more than six years old, many functional details haven’t been documented, and the test code is incomplete. Multiple product teams worked on this app.
With greenfield, there are too many uncertainties, the communication cost is large, and it’s difficult to make an estimate.
After careful analysis, we chose the safe and conservative approach: brownfield. We started the migration with the authentication flow, a self-contained module with low complexity.
Technology or framework selection should always be based on the actual situation of the project, weighing the pros and cons from many aspects, not just looking for what’s currently popular. For our project, we looked at multiple options before deciding on React Native, which suited the demands of our project particularly well.
Disclaimer: The statements and opinions expressed in this article are those of the author(s) and do not necessarily reflect the positions of Thoughtworks.