How to Build a Production React Native App in 2025: The Complete Stack

Michael D.

Michael D.

3/5/2025

#react-native#expo#production#stack
How to Build a Production React Native App in 2025: The Complete Stack

The Production React Native Stack in 2025

Three years ago, setting up a production-ready React Native project meant hours of configuration: linking native modules, fighting with Metro bundler, stitching together navigation, auth, payments, and push notifications from a dozen different sources. A significant portion of that time was spent on boilerplate rather than on your actual product.

In 2025, that story has changed. The ecosystem around React Native and Expo has matured to the point where a clear, opinionated, production-grade stack exists — one that lets you go from zero to a published app in days rather than weeks.

This post walks through every layer of that stack: what to use, why, and how it all fits together.


The Foundation: Expo with New Architecture

There is no longer a meaningful reason to use bare React Native for most applications. Expo has evolved from a set of convenience libraries into a full-featured development platform that handles everything from local development to CI/CD to over-the-air updates.

The key advantage in 2025 is that Expo SDK 52 ships with React Native New Architecture enabled by default. This gives you:

  • JSI — direct, synchronous JavaScript-to-native calls without the old async bridge
  • Fabric — the new concurrent renderer that makes animations and transitions smooth
  • TurboModules — lazy-loading of native modules, which cuts startup time significantly

Start every new project with:

npx create-expo-app@latest MyApp

You get New Architecture, TypeScript, and Expo Router out of the box.


Navigation: Expo Router

For navigation, Expo Router v4 is the clear choice. It brings file-based routing to React Native — the same mental model that Next.js popularised for web development.

Your file structure becomes your route structure:

app/
  (tabs)/
    index.tsx       → /
    explore.tsx     → /explore
    profile.tsx     → /profile
  auth/
    login.tsx       → /auth/login
    register.tsx    → /auth/register
  [id].tsx          → /:id (dynamic route)

This approach has several advantages over manually defined navigators:

  • Deep links work automatically — every file-based route is automatically a valid deep link
  • Typed routes — TypeScript knows every valid route in your app, so router.push('/non-existent') is a compile-time error
  • Shared layouts — wrap groups of screens in a shared layout file without duplicating header or tab bar configuration
  • API routes — write lightweight server-side handlers inside the same project

Authentication: Firebase Auth

Firebase Authentication remains the best choice for most production apps. It handles the complexity of secure token management, refresh flows, and multi-provider auth — and it integrates with Firestore security rules for data access control.

A typical auth setup covers:

  • Email/password sign-in with verification
  • Google Sign-In via @react-native-google-signin/google-signin
  • Apple Sign-In via expo-apple-authentication (required for apps that offer social login on iOS)
  • Persistent sessions via AsyncStorage or expo-secure-store

In 2025, the pattern that works best is combining Firebase Auth with a local state manager (like Zustand or React Context) to expose a simple useAuth() hook across your app:

export function useAuth() {
  const [user, setUser] = useState<User | null>(null);

  useEffect(() => {
    return auth().onAuthStateChanged(setUser);
  }, []);

  return { user, isAuthenticated: !!user };
}

Database: Firebase Firestore

For real-time data, Cloud Firestore is still the dominant choice for React Native apps that need:

  • Real-time listeners with automatic UI updates
  • Offline support out of the box
  • Tight integration with Firebase Auth security rules

The key pattern for production apps is to always abstract Firestore calls behind a service layer rather than calling the SDK directly from components. This makes testing, migration, and refactoring significantly easier:

// services/posts.ts
export async function getPostsByUser(userId: string) {
  const snapshot = await firestore()
    .collection('posts')
    .where('authorId', '==', userId)
    .orderBy('createdAt', 'desc')
    .get();

  return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
}

In-App Purchases: RevenueCat

If your app has any monetisation — subscriptions, one-time purchases, or consumables — RevenueCat is the industry standard for handling it correctly.

Why RevenueCat instead of calling StoreKit/Play Billing directly?

  • Server-side receipt validation — RevenueCat validates purchases server-side, making it much harder for users to fake purchases
  • Cross-platform entitlements — define once in the RevenueCat dashboard, read the same entitlement state on iOS and Android
  • Subscription lifecycle management — trials, grace periods, billing retries, and cancellations are all handled automatically
  • Analytics built in — MRR, churn, and LTV without any extra instrumentation

The integration comes down to initialising the SDK at app start and then checking entitlements wherever you need to gate features:

import Purchases from 'react-native-purchases';

// On app start
await Purchases.configure({ apiKey: REVENUE_CAT_API_KEY });

// Check access anywhere
const { entitlements } = await Purchases.getCustomerInfo();
const hasPremium = entitlements.active['premium'] !== undefined;

Push Notifications: OneSignal

OneSignal is the most complete push notification solution for React Native. It handles:

  • Permission requests — with a native prompt and a customisable soft-ask pre-screen
  • Segmentation and targeting — send pushes to specific users or user groups based on attributes you define
  • In-App Messages — show modal overlays, banners, and cards without sending a push, useful for onboarding flows and feature announcements
  • Deep link routing — pushes can navigate the user to a specific screen when tapped

The critical piece for production apps is linking the OneSignal External User ID to your authenticated user:

import OneSignal from 'react-native-onesignal';

// After sign-in
OneSignal.login(user.uid);

// After sign-out
OneSignal.logout();

This lets you send targeted pushes to specific users from your backend or the OneSignal dashboard.


Attribution: AppsFlyer

Once you start running paid acquisition campaigns, you need mobile attribution to know which channel, ad, and creative is driving installs and revenue. AppsFlyer is the industry leader for this.

What AppsFlyer gives you:

  • Install attribution — know whether a user came from Facebook, Google, TikTok, or organic
  • Deep link routing — users who click your ad land on the right screen inside your app, even if they need to install first (deferred deep links)
  • In-app event tracking — track purchases, sign-ups, level completions, and any other meaningful event
  • Fraud protection — filter out bot installs before they skew your data

UI Components: HeroUI

The days of building every component from scratch or wrestling with unstyled libraries are over. HeroUI (built on React Aria) gives you a complete set of accessible, beautifully designed components that work on both React Native and web.

HeroUI components are composable and fully customisable with Tailwind-style utility classes. You get buttons, inputs, modals, sheets, cards, badges, and more — all with accessibility support built in.


AI-Assisted Development with Cursor and Claude

One of the most significant shifts in mobile development in 2025 is how AI coding tools have changed the workflow. A well-structured React Native codebase — with TypeScript, clear file organisation, and consistent patterns — is something that tools like Cursor, GitHub Copilot, Google Gemini Code Assist, and Claude can navigate and extend with remarkable accuracy.

Practical ways AI tools accelerate React Native development:

  • Generating screen scaffolding — describe a screen and have Cursor generate the full component, including hooks, state, and navigation
  • Writing integration glue code — AI is very good at generating the boilerplate for connecting Firebase, RevenueCat, and OneSignal together
  • Refactoring — asking Claude to extract a component, rename a prop across files, or convert a class component to a functional one
  • Writing tests — AI tools can generate unit tests for your service layer and integration tests for your navigation flows
  • Debugging — paste an error and the relevant code, and get a precise diagnosis

The key to getting the most out of AI tools is starting with a clean, well-typed codebase. Consistent patterns, good TypeScript types, and clear file structure give AI tools the context they need to generate correct output.


Over-the-Air Updates: EAS Update

Expo Application Services (EAS) handles the full app lifecycle:

  • EAS Build — cloud builds for iOS and Android without needing a Mac for iOS builds
  • EAS Submit — automated submission to the App Store and Play Store
  • EAS Update — ship JavaScript and asset updates to users instantly, without going through app store review

OTA updates are particularly powerful for fixing bugs. A critical bug that would previously require submitting a new app version and waiting for review can be fixed in minutes:

eas update --branch production --message "Fix checkout crash"

Putting It All Together

Here is the full stack summary:

| Layer | Tool | Why | |---|---|---| | Framework | Expo SDK 52 | New Architecture, managed workflow, EAS | | Navigation | Expo Router v4 | File-based, typed routes, deep links | | Authentication | Firebase Auth | Multi-provider, token management | | Database | Firestore | Real-time, offline, auth-integrated | | Payments | RevenueCat | Cross-platform entitlements, receipt validation | | Push Notifications | OneSignal | Segmentation, in-app messages, deep links | | Attribution | AppsFlyer | Install tracking, deferred deep links | | UI Components | HeroUI | Accessible, composable, cross-platform | | CI/CD & OTA | EAS | Build, submit, update |

This stack covers every layer of a production mobile app. Each tool is best-in-class for its category, they integrate well with each other, and all of them are actively maintained with excellent React Native support.


Skip the Setup

If this stack sounds like exactly what you need but you don't want to spend days configuring and integrating all of it from scratch, that's precisely what CodeBaseHub is.

The CodeBaseHub React Native Starter Kit ships with every tool in this stack pre-integrated, configured, and documented — so you can open the project and start building your actual product on day one.