Expo + RevenueCat: The fastest way to make money with your app
Developmentâ˘React Nativeâ˘â˘13 minutes read
Perttu Lähteenlahti
Guest Author
Add in-app subscriptions to your Expo app with RevenueCat. Follow this guide to install SDKs, set up stores, and launch a custom paywall in minutes.

đĄTL;DR: Want to add in-app subscriptions to your Expo app? This guide walks you through setting up RevenueCatâs React Native SDKs, creating store listings for iOS and Android, and deploying a custom paywall using RevenueCatâs visual editor. With Expoâs dev build tools and RevenueCatâs UI components, you can go from zero to monetized in under 20 minutes.
If you're building an app with Expo, adding in-app subscriptions shouldn't be a major hurdle. While in-app purchases can be tricky to implement and manage across platforms, tools like RevenueCat can simplify the process. With support for both iOS and Android, and full compatibility with React Native, RevenueCat handles the underlying infrastructure so you can focus on your app.
In this guide, we'll walk through how to integrate RevenueCat into an Expo app. You'll learn how to install the necessary SDKs, set up products and offerings in the app stores, and create a custom paywall that restricts access to premium content. The goal is to get subscriptions working in your app with minimal time and friction.
Getting started with RevenueCat and Expo
Before we dive into the code, letâs cover what youâll need and how everything fits together.
Prerequisites
To follow this guide, make sure you have:
- Expo development environment set up
- A RevenueCat account
- Access to the Apple Developer Program and Google Play Console
- EAS (Expo Application Services) configured for your project
First is the RevenueCat SDK powering purchases, called react-native-purchases. It works on both iOS and Android, and allows your app to:
- Purchase subscriptions
- Restore previous purchases
- Track purchases across platforms
- React to subscription events (like renewals or cancellations)
The second dependency is react-native-purchases-ui. This includes a set of prebuilt native UI components, such as paywalls and customer center views, that you can integrate directly into your app. These components can be fully customized in RevenueCat's Paywall Builder, making it easy to create compelling subscription screens that drive conversions.
â ď¸ While these SDKs can technically be added to an Expo Goâbased app; purchases won't work in Expo Go because it doesn't include all the native APIs required (it's a sandbox!). You can still build out your UI and logic, but for actual testing and production use, you'll need a development build using Expo Dev Client and EAS Build.
We'll cover how to set up that development build in the next section.
Step 1: Install RevenueCat SDKs and create your dev build
The first step is to create an app with Expo, install the Expo CLI tools, make a development build and install the required packages.
Navigate to your project folder. Letâs first install required dependencies: expo-dev-client, and then two react-native-purchases packages:
-Â npx expo install react-native-purchases react-native-purchases-uiYou now have all the dependencies needed to purchase products and display paywalls. You can at this point run your project to ensure that everything works.
The expo-dev-client will allow you to create development builds of your app. In this guide we are going to build our development builds using EAS, as it requires no native build tools to be installed on the device we are building with. You can also build locally using EAS CLI, or without EAS entirely if you have native tooling set up. Check Expo's documentation for detailed options.
Step 2: Configure your products, offerings, and our paywall
The next steps are mostly done outside of your app, but they are essential before you can begin testing purchases. Now that we have the base app set up, we'll step away from the code briefly to configure both RevenueCat and the app store accounts where your app will be published.
As mentioned earlier, we want our app to offer subscriptions on both iOS and Android. This requires you to have both an Apple Developer account and a Google Play Console account. RevenueCat has detailed and up-to-date documentation on how to complete these steps in the SDK Quickstart guide, so we won't cover every detail here. At a high level, you'll need to complete the following:
- Create a RevenueCat project and configure it in your dashboard.
- Set up your app in App Store Connect, and add the subscription products.
- Do the same for Google Play Console, making sure the app and subscriptions are correctly configured.
Both Apple and Google require your app binary to be uploaded and reviewed before subscriptions can be added, so these steps need to be completed before any testing is possible. Fortunately, Expo's EAS Submit simplifies this processâyou can submit your builds directly to both stores using the EAS CLI.
Once your app store accounts are ready and your app is uploaded, it's time to create the subscription products that users will purchase. For this guide, we'll be setting up a monthly subscription on each platform. You'll create one subscription in App Store Connect and another in Google Play Consoleâthese should both represent the same subscription tier.
Next, head to the RevenueCat dashboard to mirror the products you just created in the app stores. Youâll do this by setting up an entitlement, a product, and an offering.
- Create an entitlement An entitlement represents the access level or feature your app will unlock after a successful purchase. In this guide, weâll use an entitlement called "pro", which your app will later check to determine if the user has access to premium features. Learn more about entitlements â
- Add your products Each subscription product you created in App Store Connect and Google Play Console (for example, a monthly subscription) should now be added to RevenueCat. These products will be associated with the "pro" entitlement so RevenueCat knows what features they unlock. Learn more about adding products â
- Set up your offering Offerings are groups of one or more products that you want to display to users in your app. For this example, create a default offering that includes the monthly product from each store. Youâll reference this offering in your app when you display the paywall. Learn more about offerings â
Once complete, you'll be ready to integrate the SDK and display your paywall in the next step.
Step 3: Integrate react-native-purchases and react-native-purchase-ui
Once you have a development build of your app, both app stores configured with the apps and the subscriptions you want to have in your app, itâs time to update the code in our app to initialize the SDK and show a paywall.
You can find the full code for doing this here, but letâs go through the parts in detail to understand what is happening:
How to Initialize the SDK
We need to initialize the RevenueCat SDK with Purchases.configure call. Add the following code to the entry point of your app. If youâre using Expo router in your project this means the top most _Layout.tsx component, otherwise it is most likely your App.tsx file. Notice that everything needs to be called in a useEffect hook without any dependencies, to initialize the SDK only once.
import { Platform, useEffect } from 'react-native';import { useEffect } from 'react';import Purchases, { LOG_LEVEL } from 'react-native-purchases';//...export default function App() {useEffect(() => {Purchases.setLogLevel(LOG_LEVEL.VERBOSE);if (Platform.OS === 'ios') {Purchases.configure({apiKey: <revenuecat_project_apple_api_key>});} else if (Platform.OS === 'android') {Purchases.configure({apiKey: <revenuecat_project_google_api_key>});}}, []);
We are first calling the setLogLevel to start logging. This will help us to notice problems in our setup, for example if we are calling things with the wrong API key. Take a look at RevenueCatâs debug log guide if you start seeing any error messages.
After that we do the actual initialization using separate keys.These keys can be found on the RevenueCat dashboard. Since iOS and Android have different keys we need to detect which platform the app is running using the Platform.OS.
Once you run your app you should not see any visual changes but there should be logs telling about successful initialization of the RevenueCat SDK. In case there are any problems or error messages, double check the previous checks. If youâre running into problems with native modules missing, rebuild your app completely.
Step 4: Displaying our paywall
Next we want to display our subscription options to the users using a paywall. To do this completely we first need to create a new paywall in RevenueCatâs paywall editor, and then add the paywall component to our app.
Creating a paywall in RevenueCat
Navigate to your RevenueCat dashboard and select your project if you have not already. In the navigation on the left you see Paywalls under âMonetization toolsâ, click that and then â+ new paywallâ
Before presenting you with the paywall starters, it asks you to choose an offering to use. We created this in an earlier step, so select the offering you created. Alternatively you can also select the option to âcontinue without adding an Offeringâ
You have the option to create your paywall from scratch using RevenueCatâs visual paywall builder, or select from the premade templates. In this case since weâve configured our product with annual and monthly options, Iâm going to select the first option available.
You can fully customize what is shown on the paywall screen in this editor; from copy to colors and even custom components like feature carousel. Once youâre happy with the paywall, press Publish paywall to deploy the changes youâve made. RevenueCat will automatically fetch changes to the paywall when you open the app, so you can always make changes to it without having to deploy a new version of your app to app stores.
Adding the paywall component to your app
For displaying the paywall we have few different options:
- Using
RevenueCatUI.presentPaywall: this will display a paywall when invoked. - Using
RevenueCatUI.presentPaywallIfNeeded: this will present a paywall only if the customer does not have an unlocked entitlement. - Manually presenting
<RevenueCatUI.Paywall>: this gives you more flexibility on how the paywall is presented.
In this project we want to present the user with a paywall that restricts user from accessing the app before they have subscribed. This is not the most user friendly option, but enough for us for now. Easiest way to achieve this behavior is to use the presentPaywallIfNeeded function
Insert the following code in the same place where you initialized the RevenueCat SDK but in a separate hook. This call is asynchronous. We need to call it asynchronously in a useEffect. Now save your changes and wait for the app to reload. If everything is initialized correctly your app should open and shortly after present the user with the paywall we configured in the dashboard.
import { useEffect } from "react";import { Button, Text, View } from "react-native";import RevenueCatUI, { PAYWALL_RESULT } from "react-native-purchases-ui";export default function Index() {useEffect(() => {const checkPaywall = async () => {try {const paywallResult = await RevenueCatUI.presentPaywallIfNeeded({requiredEntitlementIdentifier: "pro"});if (paywallResult === PAYWALL_RESULT.PURCHASED ||paywallResult === PAYWALL_RESULT.RESTORED) {console.log("User has access to pro features");// Handle successful purchase or restore here}} catch (error) {console.error("Error presenting paywall:", error);}};checkPaywall();}, []);return (<Viewstyle={{flex: 1,justifyContent: "center",alignItems: "center",}}><Text style={{ marginBottom: 20 }}>RevenueCat Paywall Example</Text><Buttontitle="Show Paywall"onPress={() => RevenueCatUI.presentPaywallIfNeeded({requiredEntitlementIdentifier: "pro"})}/></View>);}
Hooray! You now have working subscriptions and a paywall to prompt the user to get them to pay. Try purchasing any of the two subscriptions on the paywall and after a successful payment the paywall should disappear and you now have full access to the features of your app.
Conclusion
Adding in-app subscriptions to your Expo app doesn't have to be a time-consuming or technically daunting task. With the features provided by RevenueCatâs React Native SDKs, developers can focus less on backend infrastructure and more on building experiences that delight users.
In this guide, weâve walked through the complete process of setting up subscriptions in an Expo app â from installing the necessary SDKs, creating a development build, and configuring your products and offerings, to customizing and deploying a paywall with RevenueCatâs powerful UI tools. With just a few lines of code and minimal setup effort, your app is now capable of handling cross-platform subscription logic, entitlement checks, and user-friendly monetization flows.
Now that you have a working paywall and subscription system, the next step is to experiment with your offerings, iterate on your paywall design, and monitor your metrics in the RevenueCat dashboard; to build a sustainable subscription-based business with ease.


