Customers sign in with the accounts they already have
Sign-in is a module you pick at setup. It reads the keys of the provider your web app already uses, so the app and the web share one list of users. ReadyNative ships three:
- Supabase. Put the project URL and anon key of your Supabase project in .env. Email and password, Sign in with Apple and Google sign-in, sessions, protected routes and sign-out are wired.
- Clerk. Put the publishable key of your Clerk instance in .env. Email sign-up with a verification code, Sign in with Apple and Google sign-in are wired. Production Google sign-in needs your own Google OAuth client; Clerk’s shared credentials are for development.
- Better Auth. Better Auth runs its server in the app’s API routes, with an in-memory database until you replace it. Point it at the Postgres your web app already uses and run its migration, so both read one user table. Check the migration against your existing tables before you run it.
Another provider means writing an auth module, not pasting keys. The module spec describes what one is: module spec.
Your API stays where it is
The app is a client of the API your web app already calls. The data layer you pick decides how it calls it, and every option reads its base URL from EXPO_PUBLIC_API_URL:
- REST: TanStack Query or SWR, both with a small fetch wrapper that resolves relative paths against your base URL.
- GraphQL: Apollo Client, with its normalised cache and useQuery and useMutation.
Credentials are the part to check. The app sends its session with each request: a Supabase or Clerk access token as a bearer header, or the Better Auth session cookie. The server asks the provider who the caller is, so an endpoint that reads a different cookie or token needs a change.
For server code the app needs, such as the Stripe webhook, use API routes: files in src/app/api, deployed with the app to EAS Hosting or a Node host. A native release build needs EXPO_PUBLIC_API_URL to point at that deployed server, not at localhost.
One pro entitlement on the web and in the store
The store and the web are two billing rails. ReadyNative documents running both and treating either as Pro. Setup picks one payments option, so the two-rail version is a guide you follow by hand, copying from the example app.
- Store rail: RevenueCat (StoreKit and Play Billing) or Adapty. The paywall, Restore and the entitlement check are wired. The check reads RevenueCat’s pro entitlement, or Adapty’s premium access level.
- Web rail: Stripe Checkout, opened in the system browser, sells to the signed-in user. The app’s entitlement is a live search of that user’s Stripe subscriptions, with no database.
- Merged: payments.useEntitlements() returns the union of both rails, so existing pro checks keep working. RevenueCat logs in with the same user id that Stripe stores on the subscription.
Where the boundaries are
- Stripe needs a signed-in user. The checkout route answers 401 to anyone who is not signed in, so a visitor signs in before paying on the web.
- Subscriptions sold before this don’t carry the user id the entitlement search looks for (metadata.app_user_id). Those customers need the subscriptions tagged, or the lookup changed to match how your web app records them.
- Storefronts decide where Stripe shows. On iOS, the app may link to web checkout only on the US storefront, and the paywall hides the Stripe option elsewhere.
- A web buyer can also buy in the store on another device. Nothing stops that; the paywall hides both options once pro is active on the device in use.
- Refunds and cancellations reach both rails: RevenueCat’s customer-info listener and the Stripe webhook drop the entitlement.
- A purchase made before sign-in moves to the account at the next sign-in. What RevenueCat does with it is RevenueCat’s decision.
- Fees differ. Apple and Google keep 15 to 30 percent of store sales; Stripe takes its card fee. Price the store product for that.
- Adapty has no ready web-checkout example. Its access levels take RevenueCat’s place, and the code that merges them with Stripe is yours to write.
Read the web checkout guide, or add a paywall for the store rail alone.
What you still build
What this is not: a tool that turns your website into an app. ReadyNative is an Expo app with the plumbing done. You build your product’s screens on it, in React and TypeScript, against the API your web app already calls.
- Your screens. The two or three things customers do most in your web app, rebuilt as native screens. Screens are React components, and navigation is files in src/app.
- Your data mapping. Which endpoints each screen calls, and any server code beyond the routes that ship with the modules.
- Anything the modules don’t cover. A custom design system, native features of your own or a large API surface add time to the plan.
- Store accounts. The Apple Developer and Google Play developer accounts are yours to open. App Review time is Apple’s and Google’s call.
Wrapper, PWA or native screens
Three ways to put a product on a phone. Each is the right answer for some teams.
| Wrapper | PWA | Native screens (ReadyNative) | |
|---|---|---|---|
| What runs on the phone | Your website in a native app shell | Your website, installed from the browser | An Expo app; you write its screens in React Native |
| Store listing | Listed in the App Store and Google Play | Not listed in either store | Listed: EAS builds and submits it |
| Sign-in | Your web sign-in, inside the app | Your web sign-in, in the browser | Your provider’s keys: Supabase, Clerk or Better Auth |
| In-app purchase | Needs native code | Not available | RevenueCat or Adapty, with the paywall wired |
| Push | Needs native code | Web push, where the browser allows it | Expo push, wired |
| Screens | Your web screens | Your web screens | Native screens you build |
| Effort to a first build | Lowest | Lowest | Highest: your screens are the work |
| Pick it if | You need an internal tool, or a quick test of demand | Your mobile web already works, and you need no store listing or in-app purchase | You want the stores, in-app purchase and push, with native screens |
The wrapper and PWA columns describe those platforms in general; ReadyNative ships neither. The native column is backed by the module docs linked on this page.
Questions
We’re a web team, not mobile developers. Can we do this?
If your team writes React and TypeScript, yes. The app is Expo: screens are React components, navigation is files in src/app, and store builds run in Expo’s cloud, so nobody has to open Xcode. What is new is the platform itself, and the docs and the two example apps cover it.
Read the QuickstartWill Apple let us sell our web plan in the app?
Within rules. Digital subscriptions sold inside an iOS app go through in-app purchase (App Review guideline 3.1.1), which is why the paywall is RevenueCat or Adapty. On the US storefront the app may link to your web checkout; elsewhere that needs Apple’s external purchase entitlement, and the web checkout guide shows the storefront check that hides Stripe where it is not allowed. This is a summary, not legal advice: read the guidelines for your markets.
Add web checkout next to the App StoreWho keeps it working when Expo and the SDKs update?
Your purchase includes lifetime updates. Releases are tagged v<version>-sdk<Expo major>, the changelog says what changed, and the update guide walks through pulling a release into an app that already ran setup.
Update from upstreamDo we have to change our backend?
Not for the screens: the app calls the API you already run, through the data layer you pick. Two things can need a change. Your endpoints must accept the token the app sends (a Supabase or Clerk access token, or the Better Auth session cookie). Server code the app needs, such as the Stripe webhook, goes in API routes in the app’s repo, not in your web backend.
API routesWhy not wrap our web app in a web view?
A wrapper is the fastest route, and for an internal tool it may be enough. Its screens still behave like the website, and push and in-app purchase need native code either way. ReadyNative is the other trade: native screens you build in React, with push, in-app purchase and store releases wired. It does not convert your site; you write the screens.
Can the whole team work on it?
A Pro license covers up to 5 developers in one company, employees or contractors. They get access to the private repository on GitHub.
License termsYour customers already have accounts.
Give them the app on the sign-in and billing they already use. Start with setup, your keys and one screen.
The modules on this page, each with its own page: Supabase · Clerk · Better Auth · TanStack Query · SWR · Apollo · RevenueCat · Adapty · Stripe · Expo Notifications · API routes. Every module.