Mobile Development

React Native app development with TypeScript

React Native builds iOS and Android apps from one TypeScript codebase, using React skills and real native views. It is a strong fit when your team already works in React, when you share logic with a web product, or when you want to ship fixes quickly. It is a weaker fit for graphics-heavy apps and for apps that need a lot of custom native code.

Start a project

What React Native suits, and what it does not

React Native lets you write an app in TypeScript with React's component model, and it renders with the platform's own native views, so a button on iOS is an iOS button. It is one of the main routes to a cross-platform app.

It fits well when:

  • Your team knows React and TypeScript, so people can move between web and mobile work.
  • You share code with a web product, such as one built with Next.js: types, validation rules and API clients.
  • The app is made of screens, forms, lists and feeds backed by an API.

It fits less well when:

  • The app is graphics-heavy, such as a game, real-time video or advanced AR. That belongs in native code or a game engine.
  • Most screens need custom native views or deep platform features. The more native code, the less you save. See native iOS and Android development.
  • You want one fully custom, pixel-identical interface on both platforms. Flutter draws its own interface and can be easier for that.

For a side-by-side view, read Flutter vs React Native.

Expo or bare React Native

Expo is a framework and toolset built on React Native. It handles project setup, navigation conventions, builds and updates. In a bare workflow you manage the native iOS and Android projects yourself. The React Native documentation recommends starting new projects with a framework such as Expo, and for most apps that is the sensible default.

AspectExpoBare React Native
Native projectsGenerated from configurationEdited directly in Xcode and Android Studio
Custom native codeDevelopment builds, config plugins and the Expo Modules APIFull freedom and full responsibility
Builds and updatesCloud build and update services are availableYou set up and maintain your own pipeline
Best forMost new appsUnusual native needs or an existing native codebase

A common worry is that Expo locks you in. Its standard preview app, Expo Go, cannot run your own native modules, but a development build can, and you can always move to managing the native projects yourself.

Native modules when JavaScript is not enough

Sooner or later an app needs something React Native does not provide: a vendor SDK, a Bluetooth accessory, a custom camera view. You add it as a native module in Swift or Kotlin, exposed to TypeScript, or as a native view. Modern React Native calls native code directly, which removes much of the overhead of its older asynchronous bridge.

Our approach is to keep the native layer thin, put a typed TypeScript interface in front of it, give both platforms the same behaviour and test on real devices. Before adopting a third-party library we check that it is maintained, supports the current architecture, works with Expo and does not add permissions you do not need.

Performance considerations

React Native has two threads to protect: the JavaScript thread, where your logic and React rendering run, and the UI thread, where the screen is drawn. Jank appears when either is overloaded. The common causes:

  • Unnecessary re-renders. Keep state local, memoise costly components and give list rows stable keys.
  • Long lists. Use virtualised list components, not a scroll view holding hundreds of rows.
  • Animation on the JavaScript thread. Use a library that runs animations on the UI thread, and animate transforms and opacity.
  • Heavy computation. Move it to native code, a background task or the server.
  • Slow start-up. Load screens lazily, trim dependencies and use the Hermes engine, which runs precompiled bytecode.

Measure on a real mid-range Android phone, in a release build, with the platform profilers. Debug builds are much slower and say little about production.

Over-the-air updates and their limits

A React Native app can fetch a new JavaScript bundle and assets when it starts, so a fix reaches users without a store release. Expo's update service is one option, and you can host your own. The limits matter as much as the feature:

  • Only JavaScript and assets change. A new native module, permission, SDK or React Native version needs a new binary through the store.
  • Store rules apply. Apple and Google allow updates to interpreted code, but not changes that alter what the app is or does after review. Read each store's current policy before using updates for new features.
  • Versions must match. An update must be compatible with the native build already on the device, so updates are tied to a runtime version.
  • Plan a rollback. Use staged rollouts and a quick way to revert.
  • It widens the attack surface. Whoever can publish an update can change the app. Protect that account with multi-factor authentication and use signed updates where the tooling supports them.

In short, over-the-air updates are for fixes and small corrections. New features go through the stores.

Testing a React Native app

Several layers work together:

  • Unit tests with Jest for logic, state and utilities.
  • Component tests with React Native Testing Library, checking what a screen renders and how it responds.
  • End-to-end tests with a tool such as Detox or Maestro, driving the real app through sign-in or checkout.
  • Type checking and linting on every change, so TypeScript catches mistakes before a test runs.

Then test on devices: older Android phones, small screens, large fonts, slow networks and Arabic. Native modules and updates need their own test cases, because they fail in ways JavaScript tests never see.

Releasing to the App Store and Google Play

A React Native app ships as an iOS archive and an Android App Bundle, like any other app. Cloud build services can produce the iOS build without a local Mac, though you still need an Apple developer account and correct signing. Beta builds go through TestFlight and the Google Play testing tracks, and phased or staged rollouts let a bad release reach few users first. Decide which update channel each build listens to, so a test update never reaches production users, and leave a buffer for store review.

Right-to-left support

React Native supports right-to-left layouts, but Arabic needs deliberate setup. Enable RTL in the app configuration and read the direction from the device language. Switching direction inside the app generally needs a restart, so plan for that if you offer a language switch.

  • Style with start and end, such as marginStart and paddingEnd, not left and right. React Native flips left and right automatically in RTL, which confuses teams that mix both.
  • Mirror directional icons yourself. Images, logos and many animations are not flipped for you.
  • Keep strings out of components, and format numbers and dates by locale.
  • Check the Arabic font on both platforms, and test forms, keyboards and mixed Arabic and English text.

See Arabic and RTL design for the design side.

Mobile security for React Native apps

The JavaScript of a React Native app ships inside the app and can be extracted and read. Every project starts with a threat review. For this stack we focus on:

  • Secure storage. AsyncStorage is not encrypted. Use a library that keeps values in the iOS Keychain and the Android Keystore.
  • No secrets in the bundle. Precompiled bytecode is not encryption. Keep real keys on the server.
  • Certificate pinning. Pin your API's public key, with a backup and a rotation plan.
  • Obfuscation. Minification and bytecode make reading harder, but treat them as a speed bump.
  • Rooted and jailbroken devices. Detection can be bypassed, so treat it as one signal and keep critical checks on the server.
  • Dependencies. A large tree of third-party packages is a supply-chain risk. Pin versions, review updates and run dependency scanning.

Our cybersecurity service tests mobile apps before release, and the guide to secure app development covers these practices in more detail.

Before you commit: list the native features your product needs and check how many have a maintained React Native library. If many do not, compare the cost with native development.

Questions we get asked

  • For most new apps, start with Expo. Development builds and config plugins cover custom native code, and the tooling reduces setup and upgrade work. Choose bare React Native for unusual native requirements or an existing native codebase. We confirm the choice in scoping, once the features you need are listed.

  • Partly. JavaScript and asset changes can be delivered over the air, which suits fixes. Native changes, new permissions and features that change what the app does need a store release, and both stores have rules on what updates may change. Check the current policies before relying on updates.

  • For most business apps, yes. Screens, forms, lists, maps and payments run well when the app is built with care. It is a weaker choice for games, real-time video or heavy on-device processing. The usual risks are long lists, re-renders and heavy work on the JavaScript thread, which we profile on real devices.

  • Yes. React Native supports RTL layouts, and a well-built app works in both directions. It needs start and end styles, mirrored icons, locale-aware formatting and testing on real devices with mixed text. Switching direction inside the app usually needs a restart. We build and review both languages from the start.

Keep exploring

Ready to build something secure?

Tell us about your product. We will reply with a clear plan.

Start a project

We would like to use Microsoft Clarity to see how visitors use the site, so we can improve it. It sets cookies and is off unless you accept. Cookie policy