Documentation

Quickstart

Follow this from top to bottom. The first version can launch without auth, without Firebase, and without any server setup.

Before you start

You need an app that already runs and a RevenueCat project (free tier is fine). You do not need auth, Firebase, or a server for the first version.

Checklist

  • Your Expo app runs locally on your phone or simulator.
  • You know which feature should become premium (export, unlimited saves, custom theme, etc.).
  • You have a RevenueCat account and project created.
  • You can make an Expo development build for testing.

Tip

What to gate first: Pick one action users clearly understand. Not the whole app. Not everything. Just one premium feature that makes the decision to buy obvious.
1

Copy PaywallReady into your app

Copy the PaywallReady folder into your app source, then install the RevenueCat SDK. This SDK talks to Apple and Google to handle purchases.

bash

1npx expo install react-native-purchases

Good to know

What this gives you: The code to load offerings, present paywalls, check if someone paid, and restore past purchases.
2

Wrap your app once with the provider

Add the provider high in your app tree. Pass no authAdapter to start with anonymous customers — no login required.

App.tsx

1import { PaywallReadyProvider } from "./paywall-ready";2 3const REVENUECAT_IOS_API_KEY = process.env.EXPO_PUBLIC_REVENUECAT_IOS_API_KEY;4const REVENUECAT_ANDROID_API_KEY =5  process.env.EXPO_PUBLIC_REVENUECAT_ANDROID_API_KEY;6 7export default function App() {8  return (9    <PaywallReadyProvider10      iosApiKey={REVENUECAT_IOS_API_KEY}11      androidApiKey={REVENUECAT_ANDROID_API_KEY}12      entitlementId="pro"13    >14      <RootNavigator />15    </PaywallReadyProvider>16  );17}

The old way

Apps force users to create an account before they can buy.

With PaywallReady

Users buy directly through Apple/Google. RevenueCat tracks it.

Tip

Anonymous does not mean fake. Apple and Google still associate the purchase with the device. Users can restore it on a new phone through their Apple/Google account. Auth is only needed later if you require cross-device sync or server-side data access.
3

Gate one premium feature

Use usePremium() inside the feature you want to protect. If the user is not premium, show the paywall. If they are, let the feature run.

screens/ExportButton.tsx

1import { PremiumGate, usePremium } from "./paywall-ready";2 3function ExportButton() {4  const { isPremium, isLoading, presentPaywall } = usePremium();5 6  if (isLoading) return <Spinner />;7 8  if (!isPremium) {9    return <Button title="Go Pro" onPress={presentPaywall} />;10  }11 12  return <Button title="Export" onPress={runExport} />;13}14 15function PaidReport() {16  return (17    <PremiumGate>18      <ReportScreen />19    </PremiumGate>20  );21}

What should happen

  • Free user taps Export.
  • The paywall appears with real prices.
  • User buys — the button immediately changes to Export.
  • No restart needed. No account creation. No extra steps.
4

Test with a development build

Expo Go cannot run real purchases because they need native code. Build a development build on your device or simulator.

bash

1npx expo run:ios

or use EAS:

bash

1eas build --profile development --platform ios

Test these before you ship

  • Paywall shows real prices (not placeholders).
  • Sandbox purchase completes without errors.
  • Feature unlocks right after purchase.
  • Restore purchases works after reinstall.
  • App remembers premium status after restart.

Watch out

Never test purchases in Expo Go. They will not work. Always use a development build, TestFlight, or Google Play internal testing.
5

Decide if you need more

Once one feature works end to end, you can ship. Most apps launch with just this. Only add auth or Firebase when your app actually needs them.

You can skip auth if

  • Premium features are local to the device
  • Users restore via Apple/Google, not your login
  • No cross-device sync is needed

You need auth when

  • Users must see purchases across devices
  • Firestore data must be user-scoped
  • You need custom user profiles or accounts