Recently I’ve talked with a few growing companies that started a React Native app or are thinking about building one. They want to figure out how to put together a team and where to go after that. Having been a React Native lead developer at my last job, I want to share my thoughts on some of the technical and organizational things that come with adopting it. This article is intended for the startup founder or CTO who’s already decided on React Native. I’ll touch on (1) the advantages and disadvantages, (2) how to make up your team, and (3) how to proceed with your project.
1. Understanding the advantages and disadvantages of React Native
Some of these points have been talked to death, but they’re good to keep in mind as you make decisions for your company.
Companies use React Native to build apps faster:
- On its own, React is a big paradigm shift in building user interfaces. In the time of the ancients, developers had to clumsily bind templates to controllers and imperatively change elements on the screen. React lets you build UI declaratively as a representation of your app state. That probably sounded all technical, but it just means that when the app state changes, React will automatically redraw the UI, because it’s 2018.
- Iterations during development are faster. In ye olde days, developers had to rebuild the application to see changes. In React Native you have Hot Module Reloading, which lets you change the app as its running. Even better, you can use Storybook to build UI components in isolation, independent of the app. No more having to navigate 3 screens in to see if you tweaked a button correctly.
But going with React Native is a tradeoff. These are the disadvantages that I’ve experienced:
- React Native is not as well supported as native iOS and Android. Those platforms have companies whose business is supporting their platforms. React Native is mainly an internal Facebook development tool that happens to get open sourced. Facebook doesn’t dedicate as many resources to this platform as Apple and Google do. Because of that you have to be constantly on the hunt for information. A lot of my knowledge about RN comes from blog posts, Github issues, tweets, and conversations at conferences.
- At the same time, React Native evolves really fast. The monthly releases often have breaking changes, and if they don’t break your app they might break a tool or library you depend on. Upgrading React Native is a bit painful. You could neglect development of an iOS or Android app for 6 months and it wouldn’t be outdated. That’s not the case for React Native.
If you already have apps built for both platforms and an existing development team to support that, React Native is probably not for you. This we can learn from AirBnB. As one of the most respected engineering teams out there, they bet early in React Native, but had to give up the effort because of the technical and cultural difficulties of “brownfield” development. Leland Richardson (@intelligibabble) talks about React Native in the brownfield here. Gabriel Peal (@gpeal8) writes about sunsetting React Native here.
However, some companies with existing apps choose to build one natively, one in React Native. If you already launched an iOS app and want to build an Android one, go with React Native. But this choice depends on your development needs. Erica Cooksey (@EricaCooksey) has an excellent talk about choosing native development for Android while using React Native in iOS.
2. Building out your team
I would start out with someone who comes to React Native from a native developer background. React Native attracts a lot of web developers who want to make apps. But React Native doesn’t replace native development, it actually makes things more complicated because you have to be competent with React, iOS and Android at the same time. Your app development will encounter lots of hurdles in the native layer, so it’s good to start with someone who has a solid foundation.
In an ideal world, you want to have an iOS expert and an Android expert on your team. If you can only afford one native developer, go for Android. React Native on iOS is easier to manage than on Android. iOS is not as fragmented, and most people in tech (in the US), are iPhone users. Those two factors mean that iOS React Native development gets much more attention and is more stable. Android is going to give you issues and you want someone who understands that platform.
After you hire your React Native lead developer, you should hire two more people who are comfortable in React. They don’t need to have native mobile experience, and they don’t need to have a specific level of seniority. But make sure you hire people who are into the idea of building a mobile app — don’t bring in a skeptical web developer. The React Native developer experience isn’t as nice as it is for web, and they’ll quickly miss their comforts.
I think a team of 3 dedicated developers should be enough, but obviously that depends on the growth stage of your company. Your lead developer will probably spend half their time writing features, and half their time maintaining the project and supporting the other developers.
On top of that, I would make sure to hire a designer who understands mobile applications, instead of trying to leverage web-specialized designers. It doesn’t matter how good your development team is if your users find the app difficult to use. An app should have a very different UX than the mobile-sized version of your web app. You don’t want it to have 10 input fields inside a scrollview in a tiny screen. It’s important to have a designer who understands this. React Native also lets you do innovative things with gestures and animations easily, so get a designer who’ll want to leverage that.
Avoid keeping your developers in a bubble. I recommend that you send them to at least one conference per year. It’s a really good way to stay current and build relationships with knowledgeable people. Your devs will come back to work with a ton of new knowledge, techniques, and insider information they’ll want to apply at work. I’m not sure why most companies put the responsibility of growing on the developers, but if you’re selfish and want the best team possible, invest in their growth.
3. Managing your project
Once you have your project and team set up, you can start leveraging your existing web codebase and web development team. If you have auth and API client code already written for web, split it out into its own project so you can use it with your app. Developers from your web team will be excited to build features for mobile, but they’ll get grumpy with build issues or native-layer bugs. Have your RN lead write really good guides and act as tech-support for the native layer.
Set up TypesScript.
Build a design system.
If you want to go at ludicrous speed, create a design system for your app. A design system is a collection of reusable components following clear guidelines. It’s a collaboration between developers and designers to create a shared UX language, and helps in creating a uniform user experience.
A design system is important for development speed because it keeps designers and developers on the same page (🥁). Sometimes designers build screen first rather than to component first. When designers focus on whole screens, there can be variations introduced in spacing, font sizing, colors, etc. When developers have to build entire screens from scratch, they can get overwhelmed (or be lazy) about the details. Without a design system, over time it becomes hard to update old screens and your app will lose its uniformity.
Teams that work this way tend to blame developers for not being detail-oriented enough. If you’re getting swamped in the details, work to reduce the complexity of your designs. It’s much easier to specify screens as collections of components with well defined guidelines. Having a design system as reference simplifies communication between your teams, keeps everyone honest, and speeds up feature development.
If you already have an existing app, starting a design system recreating your designs might seem too much effort. Trust me, stop what you’re doing and create one now. You have no idea how much time you’ve been wasting. You can easily take your design system from Sketch to code with Storybook. Samantha Bretous (@samanthabretous) has a great talk on building a component kit.
What about universal components? React on the web and React Native are very similar but they have key differences, (i.e. `<div />` vs `<View>`, CSS vs StyleSheet, different platform capabilities). Universal components are React components built to work in both platforms. If you’re building a product for both platforms you might be tempted to go that route. In my experience, since it’s not painful to make a React component twice, I haven’t felt the need to. Kurtis Kemple (@kurtiskemple) implemented them during his time at MLS and you can read about his experience here.
Set up your build process.
You’ll want your RN lead to create a beta and a production version of the app. The beta version points to your non-production backend, and has the very latest changes for your team to try out. You can use Fastlane to automatically deploy to the app stores. Gant Laborde (@GantLaborde) wrote a guide on how to set it up. You can take this even further by using Github webhooks to automatically deploy the beta app whenever the master branch changes, and releasing the production app whenever a new release is tagged.
If you want to avoid shipping bugs in the first place, invest in Detox for end-to-end testing. The most common types of bugs I’ve had to deal with are regressions. Features in development get the most QA attention before a release, and sometimes changes for new features can break old ones. It’s particularly bad when regressions go unnoticed for months. You can have some peace of mind and save your QA team a lot of time by implementing Detox in your build process. Here’s a quick explanation and demo of E2E testing with Detox. There’s a much more extensive article by Rotem Mizrachi-Meidan (@rotemmiz) here.
A note about CodePush: If you automated your releases with FastLane, you could use a semver versioning scheme to sometimes release via CodePush. A `minor` version bump could indicate a a full release (aka you have changes in native code), and a `patch` version bump could indicate a CodePush release. For example, if you’re on version `2.3.1` of your app, tagging version `2.3.2` gets the CodePush treatment, while tagging version `2.4.0` gets the App/Play store treatment.
Maintain the hell out of your app.
As I mentioned earlier, RN is still evolving very quickly. It’s like a wild horse. You can ride it and go fast, but if you’re not paying attention it can buck you and leave you behind. So every month, when the new version of React Native comes out, your team needs to make a strategic decision about when you’re going to do the upgrade. Does the upgrade have things you need? Does it affect your 3rd party dependencies? How bad are the breaking changes and how do you balance that with your project schedule? There’s definitely more platform maintenance than on native apps, but the speed advantage more than makes up for it.
I hope you found this article useful in deciding where to go with React Native. If you need more advice, you can write to me at email@example.com.