React Native is an open-source cross-platform framework for building mobile applications with JavaScript or TypeScript and the React component model, while rendering real native UI components on iOS and Android rather than a web view. In app development it sits between fully native development and frameworks such as Flutter that draw their own interface, offering one shared codebase with native look and behavior.
In the mobile domain, React Native is chosen mainly for team efficiency: web developers who already know React can ship mobile apps, and a single product team can maintain both platforms from most of the same code, typically sharing a large majority of business logic and UI.
How React Native turns components into native views
A React Native app runs its JavaScript code in an embedded engine, usually Hermes, which compiles JavaScript to bytecode ahead of time for faster startup and lower memory use. React computes which components changed, and the renderer translates those changes into operations on native views such as UIView on iOS and android.view.View on Android.
The New Architecture, now the default in current releases, replaced the older asynchronous bridge. JSI (JavaScript Interface) lets JavaScript call C++ objects directly, TurboModules load native modules lazily, and the Fabric renderer performs layout with the Yoga engine and can render synchronously when needed. Together they remove the cost of serializing every message to JSON.
The table summarizes the main layers and their role.
| Layer | Technology | Role |
|---|---|---|
| JavaScript engine | Hermes | Runs application logic and React |
| Interface layer | JSI | Direct calls between JavaScript and C++ |
| Renderer | Fabric with Yoga | Computes layout and updates native views |
| Native modules | TurboModules | Access to camera, storage, sensors and platform APIs |
| Platform UI | UIKit and Android views | Draws the actual on-screen controls |
Key characteristics and development workflow
Daily work in React Native relies on Fast Refresh, which applies code changes to a running app in about a second while preserving component state. The Metro bundler packages JavaScript, and many teams use Expo, a framework and toolchain around React Native that provides prebuilt modules, cloud builds and over-the-air updates for JavaScript changes.
Code sharing is high but rarely total. Platform-specific files such as Button.ios.tsx and Button.android.tsx, or the Platform API, handle differences in navigation patterns, permissions and visual conventions. Features without a ready library require a custom native module written in Swift, Objective-C, Kotlin or Java.
| Characteristic | Typical value or behavior | What it depends on |
|---|---|---|
| Shared code | Most logic and UI, rarely all | Amount of platform-specific features |
| Refresh cycle | About one second with Fast Refresh | Bundle size and machine speed |
| Binary size overhead | Several megabytes for the runtime | Engine, architectures and libraries |
| Over-the-air updates | JavaScript and assets only | Store rules forbid changing app purpose |
| Native code needed | Occasional custom modules | Use of new or niche platform APIs |
React Native compared with Flutter and native toolkits
The central difference among cross-platform options is who draws the pixels. React Native maps components to platform widgets, Flutter paints every pixel with its own engine, and SwiftUI and Jetpack Compose are the native declarative toolkits of each platform.
| Approach | Language | Rendering | Platforms from one codebase |
|---|---|---|---|
| React Native | JavaScript or TypeScript | Native platform views | iOS and Android, plus community targets |
| Flutter | Dart | Own engine draws all widgets | iOS, Android, web and desktop |
| SwiftUI | Swift | Native Apple views | Apple platforms only |
| Jetpack Compose | Kotlin | Native Android rendering | Android, with multiplatform variants |
| Native app | Swift or Kotlin | Platform toolkits | One platform per codebase |
React Native gives the most platform-faithful controls among cross-platform options, because a text field really is a native text field with native accessibility and input behavior. Flutter gives more pixel-identical consistency across platforms. Native toolkits give first-day access to new APIs and the most predictable performance, at the cost of two codebases.
When to choose React Native
React Native fits best when an organization already uses React on the web, needs both mobile platforms and builds mostly forms, lists, content and commerce flows. It is a weaker fit for apps dominated by heavy graphics, real-time audio or deep hardware integration.
| Situation | Recommended choice | Reason |
|---|---|---|
| Web team with React skills | React Native | Reuses skills, patterns and some logic |
| Content or commerce app | React Native or Flutter | Standard UI, fast iteration on both platforms |
| 3D game or advanced graphics | Game engine or native | Rendering needs exceed UI frameworks |
| Watch, widget or car extensions | Native for those parts | Limited cross-platform support |
| Existing native app | Brownfield integration | Add React Native screens gradually |
Limitations and common pitfalls
Most React Native problems come from the boundary between JavaScript and native code and from the dependency ecosystem, not from React itself.
- Unnecessary re-renders in long lists, solved with virtualized lists, memoization and stable keys.
- Heavy work on the JavaScript thread, which delays touch handling; move it to native modules or worklets.
- Abandoned third-party libraries that block upgrades to new React Native versions.
- Delayed upgrades that accumulate breaking changes and make later migrations expensive.
- Assuming identical behavior on both platforms without testing gestures, keyboards and permissions separately.
A practical rule is to upgrade regularly, prefer well-maintained libraries and keep a developer on the team who can read Swift and Kotlin, because every serious React Native app eventually needs native debugging.
The short version
React Native lets a team write a mobile app once and run it on both iPhones and Android phones. The code uses the same language as many websites. Yet the buttons, menus and text fields on screen are the phone’s own built-in controls.
Think of one recipe cooked in two kitchens. Each kitchen uses its own local ingredients. The dish is the same, but each version feels at home where it is served. The result looks and feels native, and the team keeps mostly one set of instructions.
Where it makes a difference
A regional grocery chain has a React web shop and a team of six web developers, but no mobile specialists. It needs a shopping app for iOS and Android within six months. Using React Native with Expo, the team shares product listing, cart and checkout code across both platforms and reuses validation logic from the website.
Only two features need native work: barcode scanning and integration with a payment terminal SDK, handled by one contracted native developer. The apps launch on both stores in the planned window, and later price-display fixes ship as over-the-air JavaScript updates within hours instead of waiting for a full store review.