React Native App Development: When It Fits and How We Build It

When React Native is the right choice, what its new architecture changes, where native modules come in, and what over-the-air updates can and cannot do.

One blueprint projected into two phone outlines with identical screens, as one React Native codebase builds both apps.

React Native app development lets one team ship an iOS app and an Android app from a single TypeScript codebase, while the screens render real native components rather than a web page. For a large class of products, it is the most economical way to be on both stores with an app that feels right on each.

It is not free of trade-offs. Good React Native work means knowing where the framework ends: which features will need native modules, what over-the-air updates can and cannot do, and when the honest answer is to build natively instead. This article covers how we make those calls.

What we build with React Native

  • Marketplaces with buyer and seller flows, listings, messaging and payments.
  • Booking, ordering and account apps that sit on top of an existing backend.
  • Shopping and loyalty apps with catalogs, carts and push campaigns, the subject of our article on m-commerce app development.
  • Financial app front ends that combine standard screens with native SDKs for identity verification or card scanning.
  • Companion apps for IoT devices, with a native module handling the Bluetooth protocol.
  • Internal and field apps, where one codebase keeps the maintenance burden small.

A common thread is a React web product next door. Types, API clients, validation and business logic can be shared between the web app and the mobile app in one repository, and the same engineers can move between them.

Is React Native app development the right fit?

React Native fits when:

  • You need both iOS and Android, with one team and one roadmap.
  • The app is mostly screens: lists, forms, media, maps, and payments through provider SDKs.
  • Your team, or the team that will own the app later, knows React and TypeScript.
  • You want to share code and people with a React web application.

It does not fit when:

  • The core of the product is heavy graphics, 3D or a game; a game engine or native code will serve you better.
  • The app processes camera, audio or sensor data in real time, or augmented reality is the main feature.
  • Most of the value lives outside the app, in widgets, a watch app or CarPlay, all of which are native code anyway.
  • Startup time and memory on very low-end devices are critical, since React Native adds a JavaScript runtime to every launch.
  • You need each new OS feature on the day it ships.

For those products, read our take on native mobile app development. And if you mainly need reach rather than store presence, an installable web app may be enough; HTML5 app development covers that option.

The new architecture, and what it changes

For most of its history, React Native connected JavaScript to native code through an asynchronous bridge that serialized every message. It worked, but batching and serialization added latency, and anything that needed an immediate answer from the native side, such as measuring a layout during a gesture, was awkward. The new architecture removes that bridge and is built from four pieces:

A slow bridge carrying queued parcels above a direct beam, contrasting the old bridge with the new direct interface.
  • JSI, a C++ interface that lets JavaScript hold references to native objects and call their methods directly, including synchronously when that is appropriate.
  • TurboModules, native modules that load lazily and expose typed interfaces instead of loosely typed messages.
  • Fabric, the new rendering system, which can measure and update layout synchronously and supports React’s concurrent features.
  • Codegen, which generates the glue between JavaScript and native code from typed specifications, so mismatches fail at build time instead of in a user’s hands.

Alongside it, the Hermes engine compiles JavaScript to bytecode at build time, which shortens startup and lowers memory use. In practice, this means smoother gestures and animations, faster launches and native modules that are easier to write safely.

It also means a dependency audit. Every library in the app must support the new architecture, and unmaintained libraries are the main obstacle when we migrate an older app. We upgrade React Native versions in steps, replace abandoned packages and retest every native integration.

For new apps we start with Expo, the framework the React Native team recommends. Development builds and config plugins mean Expo no longer limits which native code you can use, and generating the native projects from configuration makes version upgrades far less painful. Brownfield projects, where React Native screens are added to an existing native app, need a more hands-on setup.

Native modules: planning for Swift and Kotlin

Most needs are covered by well-maintained libraries: navigation, camera, maps, secure storage, push notifications, and the official React Native SDKs many payment providers publish. Animations and gestures run on the UI thread with Reanimated and Gesture Handler, and long lists use a recycling list component so scrolling stays smooth.

Some things still need native code:

  • Vendor SDKs with no React Native wrapper, such as some identity verification, card reader or proprietary hardware SDKs.
  • Custom Bluetooth protocols for IoT devices, and background processing with platform-specific rules.
  • Home screen widgets, Live Activities and watch apps, which are written in Swift or Kotlin and share data with the main app through app groups or shared storage.
  • Performance-critical paths such as image processing.

We write these with the Expo Modules API or as TurboModules, with typed interfaces on both sides. That is why we staff React Native projects with engineers who are comfortable in Xcode and Android Studio: signing, Gradle and native build errors are part of the job. When we choose libraries, we look at maintenance activity, new architecture support, TypeScript types and how issues are handled, and we treat a short dependency list as a feature.

Over-the-air updates: useful, with caveats

Because much of a React Native app is JavaScript, you can ship a new bundle directly to users without a store release, using Expo’s EAS Update or a self-hosted update server. Used well, it is a safety net for urgent fixes and a quick way to adjust copy and small UI details. The caveats:

An update package rolling out through test and production channels, reaching only some phones, with a rollback path.
  • Only JavaScript and assets can change. A new native module, an SDK upgrade, a new permission or a React Native upgrade needs a store release. Each update must target the native runtime it was built for, or it can crash older installs.
  • Store rules still apply. Apple allows downloaded JavaScript only within limits: it must not change the app’s primary purpose or introduce features that skip review. Google Play allows interpreted code updates, but its policies still apply to whatever you ship. Use updates for fixes and refinements, not for launching features reviewers never saw.
  • Updates arrive gradually. Depending on configuration, a user gets an update on the next launch or the one after, so even an urgent fix takes time to reach everyone.
  • They need operations. Separate channels for staging and production, staged rollouts, monitoring, a rollback plan and signed update bundles.
  • They do not replace QA. A fix that can ship in minutes still needs regression testing, or you ship the next bug faster.

Quality in a React Native codebase

  • Types and tests. Strict TypeScript, unit tests with Jest, component tests with React Native Testing Library, and end-to-end tests with Maestro or Detox against real iOS and Android builds.
  • Performance. We profile release builds on mid-range Android phones, where unnecessary re-renders and oversized images show first, and keep animations on the UI thread.
  • Accessibility. Accessibility labels, roles and states map to VoiceOver and TalkBack, but the two screen readers behave differently, so we test with both.
  • Security. Tokens go in Keychain- and Keystore-backed storage, never in plain async storage, and nothing secret ships in the JavaScript bundle, which is easy to extract from an app package.
  • Store review. The same rules as any native app: privacy details, account deletion, in-app purchase for digital goods and a demo account for reviewers.

How an engagement works

A React Native team with us usually combines a business analyst, a product designer, React Native engineers (at least one of them with deep iOS or Android experience), a backend engineer when the product needs one, and QA. Work runs in short iterations. Fast Refresh keeps day-to-day development quick, each iteration ends with a demo and installable builds for both platforms, and CI builds, tests and signs every change.

You receive one repository, both store listings under your own accounts, update channels configured for staging and production, and documentation your own team can pick up. Startups often choose React Native for exactly these reasons, and mobile app development for startups covers how we scope a first release. We also take on existing React Native apps: upgrading old versions, migrating to the new architecture and replacing abandoned libraries.

Frequently asked questions

Does a React Native app feel native?

It uses the platform’s own UI components, so text, inputs and scrolling behave natively. Custom animations and gestures need care, but with the right libraries most users will not notice a difference on typical screens.

Expo or bare React Native?

Expo for almost every new app. It no longer restricts native code, and it simplifies builds, updates and upgrades. Adding React Native to an existing native app is the main case for a more manual setup.

Can we share code with our React web app?

Business logic, API clients, validation and types, yes. UI components mostly not, because web and native primitives differ; sharing UI through React Native for Web is possible but brings its own compromises.

Can you migrate our older React Native app to the new architecture?

Yes. We start with an audit of the React Native version, every dependency and every custom native module, then upgrade in steps with testing at each one. Abandoned libraries are replaced or rewritten.

What happens when a library we depend on is abandoned?

We fork and maintain it if it is small, replace it if a healthy alternative exists, or write a focused native module. Choosing libraries carefully up front keeps this rare.

If you need to be on both stores with one team, and you want a partner who will tell you where React Native stops, tell us about your product. We will tell you whether it fits, and what we would build natively if it only mostly does.