Over the years that I’ve been working with React (circa 2014) and React Native (circa 2016), I’ve had everyone from engineers to CEOs to product people ask me some form of the question, "What are the differences between React and React Native?" Developers want to know how much they have to learn, managers want to know how much their team’s velocity will be affected, and what other considerations there are.
TL;DR: mobile application development is a very different world from browser-based application development, so naturally developers will need to learn new tools, paradigms and techniques. Even though the core React API is the same, you're coding for smartphones and tablets instead of browsers, and those have a very different set of rules. In parallel, managers will have to provision some new services for their React Native projects to run effectively. But there’s a lot more to it; I encourage you to read on.
There’s a good amount of knowledge that will translate for React web developers. Enough, in fact, that this is why React Native is such a compelling choice for web engineers to start working on mobile applications. Here are things that React developers will not have to learn from scratch when starting to work with React Native.
A component is a component is a component. Class-based components and functional components operate the same way in React Native as on the web. You still should think in React apply all of your React best practices like using composition and lifting state up.
State management, orchestrating HTTP requests, synchronizing client and server state: all these things will apply to React Native. The differences will only arise when the device layer comes into play (for example, if you have to store data on the client,
window.localStorage doesn’t exist, but
useCallback() operate identically. Anything related to build optimization will be different, and React Native requires some additional attention to optimization (more on that below).
Many tools for monitoring, error reporting, analytics, etc. have SDKs that translate over well. I'm thinking Sentry, Datadog, MixPanel, others.
npm packages that don’t rely on native code or CSS will also work well in React Native. Yes you can still use your beloved
react-hook-form and React Query / Tanstack Query. State management libraries like Redux, MobX, XState, and so on are fine as well.
As you’ll notice, this section is a lot longer than the previous one 😁 React development principles will certainly translate over to native well; but it’s important to realize that React isn’t a magic bullet. Developers will still need to learn plenty about mobile development in general, and specifically how to do things well in RN.
The biggest paradigm shift when going from React web to React Native is perhaps the obvious one: you’re now building apps for completely different devices that run in a completely different environment. Mobile hardware can do things browsers can't, so that's a perk. But it also means new learning. Push notifications, in-app purchases and haptics are things that are now natively supported and have their own APIs for.
React Native uses the Yoga engine under the hood, which allows you to use CSS properties to layout your React Native UI in a way that translates really well. Layout in Yoga is limited to Flexbox and absolute/relative positioning, however; there is no CSS grid and no
display attribute. This keeps things simpler and more performant, but if developers are accustomed to using other layout techniques on the web, they’ll need to adjust to this new limitation.
React Native does come packaged with block-level (
<View> ) and inline (
<Text>) which can be thought of to parallel
<span> in html. They support a fair bit of common CSS properties: borders, backgrounds, typography and so on are all in there. But as before, don’t expect fancier properties like
calc() to be available.
CSS-based UI libs don't make sense on mobile; your new options include NativeBase, React Native Elements and others). Some web-based UI libs do have RN siblings though - such as React Native Material and React Native Paper (for Material-UI), and tailwind-rn (for Tailwind). This just means new decisions to make, some learning, and new paradigms for how to use the new libs.
A great many React libraries do indeed work on React Native as well, which is a great perk for the platform. It’s worth noting that some will have slight configuration changes to make them work on React Native. This is understandable since the environments are different (DOM vs no DOM, hardware differences, and so on).
react-hook-form, for example, uses
<form> tags on the web. But since HTML doesn’t exist in React Native,
react-hook-form requires developers to wrap their forms in a
<Controller> component, which does work in RN.
As a user, you already know that moving around a smartphone app is completely different than on a web app.
react-navigation is the most common navigation lib for mobile (runner-up:
react-native-navigation). Both are fairly different from
react-router, Next.js's router, and so on. Not only do developers have to learn new APIs for this, they’ll have to think differently to plan out complex navigation properly. It’s all very achievable, but I wouldn’t advise assuming that the effort is trivial.
Some development tools for the web are similar (Chrome debugger, mostly) to those for React Native, but other aspects are very different (working with the metro bundler, using Flipper, AsyncStorage debugging, more). Some techniques developers will use are the same (breakpoints and console logging), but others are different (knowing when to restart the packager vs reinstall the app on device).
Testing while you develop anything is crucial; the iOS simulator and Android emulators let you simulate a variety of devices. Naturally the iOS sims only run natively on a Mac, which is worthy of note, as this is a roadblock for any dev team that uses Windows or Linux and doesn’t have a Mac readily available.
Dev machine setup is also more time-consuming, and can be quirky. Devs will need to have both XCode and Android Studio installed beforehand, so that builds will compile and emulators on both platforms exist for running code.
watchman is also a prerequisite along with
rbenv) and CocoaPods — but it’s important to note that our beloved Expo makes a lot of this way easier. (It’s one of the many reasons we use it for all of our React Native projects at Echobind.)
Lastly, both the iOS simulator and Android emulators have limited or no support for certain features of smartphones: haptics, geolocation, app store purchases, and the camera, just to name a few. It’s best to have at minimum one real device for each operating system to properly test with while developing.
Besides React optimization (which is arguably more necessary on mobile), developers will now have different hardware and a different internal architecture to work with. They’ll have to know about the JS and UI threads, and different (and IMO more challenging) ways to avoid jank and prevent crashing. Memory and energy consumption are now even more important, since mobile devices are more limited in these areas.
And they’ll have to use new performance analysis tools. Have a look at React Native’s performance overview page just to get a sense of the approach.
The stakes are also higher for both devs and product teams on mobile - crashes and bad performance are huge killers of App Store reviews.
Besides all of the technical differences, development process is different for web vs mobile apps, so naturally it also will be for React vs React Native apps. So here are some of the process-related considerations for how your dev team’s workflow will be affected when transitioning from React web to mobile development.
You can deploy to prod without restriction on web; on mobile you have to deal with both app stores, which can be cumbersome and slow especially for the initial release/approval process. You have to fill out lots of documentation before the first time you release to production.
Even distributing a beta version of your app for non-developers to test, either for formal QA or for casual testing, can be a process. It’s not as easy as just deploying anymore; depending on your distribution method and which app store you’re working with (more so for iOS distributions than Google, FWIW) you may have to add each tester to the portal manually, then kickoff another build for them to be able to access it.
We use tools to simplify all of this at Echobind (like Expo Application Services, GitHub Actions and others), but we make sure to accommodate time for this in our project budgets since it can be non-trivial to set up.
Unit testing with Jest and React)Testing Library is similar on React Native; developers use the same syntax (and the React Native version of React Testing Library), so there isn’t a huge paradigm shift there. Developers will have to mock out different third-party libraries on native, though, since unit test suites won’t be able to run native code.
End-to-end testing is completely different on React Native, however. None of the Selenium-based E2E testing tools will work; neither will newer tools like Cypress or Playwright. You may have expected this - these are all DOM-based, and there’s no DOM in React Native. So instead developers will have to learn Detox or Appium.
Also since it’s mobile, you can’t avoid manual testing completely, no matter how much you automate. Plan to allocate time for testing setup in each project, since TestFlight and Play Store configuration are non-trivial (especially the former). Once again, EAS makes this easier, so save yourself frustration and use it.
And with every release, plan time to manually test each build on each platform.
Continuous Integration/Continuous delivery are a different animal for React Native apps as well. You may end up making different choices on services and tools to use, and setting them up separately.
Firstly, keep in mind that if you’re building for both Android and iOS, you’ll need to run your CI builds on a Mac (at least for the iOS builds). Which means that you’re gonna pay a LOT more for your build runs than on Linux boxes. Look at EC2’s cheapest mac instance compared to it’s cheapest Linux instance (which has more powerful hardware):
And similarly, GitHub Actions’ per-minute pricing for Linux vs MacOS instances:
A MacOS instance costs 2.5 times as much Linux instance with almost three times the processing power; but compared to a Linux instance with one less CPU core, the Mac instance costs 10 times as much (!!).
That’s just a visual way to say that you’ll need to think through your CI setup carefully, for more reasons than one.
At Echobind for example, we typically setup Expo Application Services (EAS) and GitHub Actions for our React Native client projects and internal projects. Builds get triggered by a PR merge to
main; GitHub Actions runs JS-related automation (linting, typechecking, unit tests, etc), then hands off control to EAS to do the actual builds and releases.
For us, this setup provides the a good balance of ease of setup, features, DX and reasonable costs. It also makes testing a lot easier since people can scan install builds to their phones just by scanning a QR code. But one CI setup doesn’t fit all projects, so choose yours carefully.
This is a fairly thorough list of differences between React for the web and React Native; please keep all of these things in mind when starting to learn React Native (if you’re a developer) or transitioning your dev team to React Native (if you’re a manager). Planning accordingly will save you a lot of time and frustration, and reduce surprises.
Originally published at https://echobind.com.