ReadyNative

Troubleshooting

Fixes for the most common failures - setup, bun and Node, Expo Go vs dev builds, env keys on EAS, sign-in redirects, paywalls, push and Metro.

Something broke? Here are the failures I see most, each with its fix. Start with bun run doctor (Starter and Pro): it checks the versions, your keys, the config placeholders and the EAS link in one go, and names what to fix.

setup prints "Already applied"

Symptom: bun run setup --ui tamagui (or any other flag) prints Already applied - setup is one-way and removed itself and nothing changes.

Your tree is finalized: the first setup run deleted modules/ and left this one-line stub in its place, so there's nothing to apply a new selection from. .readynative.json records what you picked. To switch an option, start from a fresh clone of your tier repo - Can I change a module after setup? has the steps. Next time, bun run setup --keep-modules keeps the tree switchable.

Wrong bun or Node version

Symptom: bun install or a script fails early, doctor shows a red bun >= or node >= line, or a script dies with an error about the .ts file extension.

scripts/*.ts run under plain node, which strips TypeScript natively only from 22.18 on, and app.config.ts imports readynative.config.ts the same way. Update both:

bun upgrade
node --version

Install Node 22.18 or newer (24 LTS is what I run) with your version manager of choice, then run bun run doctor again. With npm, pnpm or yarn instead of bun, see Package managers.

A native module is missing in Expo Go

Symptom: the app crashes on launch in Expo Go with something like TurboModuleRegistry.getEnforcing(...): 'X' could not be found or "Cannot find native module", usually right after picking MMKV, Unistyles, RevenueCat, Adapty or push.

Expo Go contains only its own bundled native modules. Those options ship native code, so they need a dev build: your own build of the app that works like Expo Go afterwards.

bunx expo run:ios
bunx expo run:android

Or build it in the cloud and install from the link:

bunx eas-cli build --profile development --platform ios

Then start Metro with bun run start:dev and open the (Dev) app, not Expo Go. Rebuild whenever you add a library with native code or change native config (readynative.config.ts ids, icons, plugins). bun run setup prints whether your selection runs in Expo Go; Expo Go or a dev build lists every module that doesn't.

A key is missing or ignored

Symptom: a screen says "Configure Supabase" (or the matching service), doctor reports missing in .env, or you added a key and nothing changed.

  • Put keys in .env at the repo root. .env.example lists every key your selection needs, each with a link to the dashboard that issues it.

  • EXPO_PUBLIC_* values are inlined into the bundle when Metro builds it, so restart with a clear cache after editing .env:

    bun run start -- -c
  • Read them as process.env.EXPO_PUBLIC_X written out in full. Expo inlines only static references; process.env[name] stays undefined.

  • Works locally but not in an EAS build? See the next section.

  • Server keys (STRIPE_SECRET_KEY and friends) never get the EXPO_PUBLIC_ prefix. The app can't read them; only src/app/api/** and src/server/** can.

A key works locally but not in an EAS build

Symptom: the app works with bun run start, but a build from EAS (TestFlight, Play internal testing, a preview build) shows "Configure Supabase" or its service's equivalent, or an update from eas update loses a key.

.env is gitignored, so EAS never uploads it. Set each key in the EAS environment the build uses, with plaintext for EXPO_PUBLIC_* keys and sensitive for server keys:

bunx eas-cli env:set --environment production --name EXPO_PUBLIC_SUPABASE_URL --value https://xyz.supabase.co --visibility plaintext

Then rebuild, or republish the update with --environment. Environment variables → On EAS says which profile reads which environment.

Supabase sign-in never comes back in Expo Go

Symptom: Google sign-in or a password-reset link opens the browser, you finish there, and the app never receives the session - you land on a Supabase error page or the site URL instead.

Supabase redirects only to URLs on its allow list. In a dev build the app's links start with your scheme (readynative://), but in Expo Go they start with exp://<lan-ip>:8081/--/. In Supabase, open Authentication → URL Configuration → Redirect URLs and add exp://** to your development project (never production), next to your scheme's entries. The Supabase page lists them all.

RevenueCat shows no offerings or no prices

Symptom: the paywall is empty, offerings.current is null, or packages load without a price.

RevenueCat can show only what the store hands it. Work down this list:

  • Paid Apps Agreement: App Store Connect → Business must show the Paid Apps Agreement as active, with banking and tax forms complete. Until then StoreKit returns no products at all.
  • Product status: each subscription in App Store Connect needs its metadata filled in so it reaches "Ready to Submit" (a price, a localized name, a review screenshot). On Play, the product must be active.
  • Offering: in RevenueCat, the products are attached to a package in an offering marked current.
  • Tester: purchases and prices come through on a real device signed into a sandbox Apple ID (or a Play license tester). A RevenueCat Test Store key (test_…) skips all of this in development.

The RevenueCat page walks the dashboards.

The push token is null

Symptom: push.usePushToken() stays at token: null with status unsupported, and the dev console warns "remote push needs a physical device".

Simulators and emulators never get a remote push token, and Expo Go doesn't receive remote push since SDK 53. Install a dev build on a physical phone (bunx eas-cli build --profile development, or bunx expo run:ios --device) and open that. If the status is unsupported on a real phone, app.easProjectId in readynative.config.ts is empty - run bunx eas-cli init and paste the id. Local notifications work everywhere except the web. See Add push notifications and the Push module page.

EAS build or credentials fail

Symptom: eas build stops before the build starts, or the build fails at signing.

  • Not logged in / wrong account: bunx eas-cli whoami, then bunx eas-cli login.
  • No project id: eas init can't write into app.config.ts; it only prints the id. Paste it into app.easProjectId in readynative.config.ts (or set EAS_PROJECT_ID in CI).
  • The project belongs to an organisation: set app.owner to the organisation slug, or CI builds with an org EXPO_TOKEN are rejected.
  • iOS signing: run the first iOS build interactively so EAS can sign in to your Apple Developer account and create the certificate and provisioning profile. A paid Apple Developer membership is required; a free Apple ID can't build for the store. "Bundle identifier is not available" means someone already registered that id - change app.ios.bundleId.
  • Inspect or reset stored credentials: bunx eas-cli credentials shows the iOS certificates, the Android keystore and the service account keys for each platform. Don't delete an Android keystore that has already uploaded to Play - you'd lose the upload key.
  • --non-interactive in CI fails on credentials: run one build interactively first so the credentials exist on EAS.

git apply says "does not exist in index"

Symptom: piping a diff between two release tags into git apply stops with error: <path>: does not exist in index and applies nothing.

git apply is all-or-nothing, and the upstream diff touches paths your finalized tree doesn't have: module files live under modules/<category>/<option>/files/ upstream but at the root in your tree, the UI kit moved to src/components/ui, and setup removed the demo screens and its own scripts. Map the paths, and let git merge around your edits:

  • For a module, add --relative=modules/<category>/<option>/files to git diff.
  • For the UI kit, add --relative=modules/ui/<your-stack>/files/src/ui/<your-stack> to git diff and --directory=src/components/ui to git apply.
  • Always pass --3way to git apply, and add --exclude=<path> for every path the error still names.

Update from upstream has the full commands.

Metro serves stale code

Symptom: a change doesn't show up, an import you deleted still errors, or the app shows "Unable to resolve module" for a file that exists - typically after bun run setup, switching branches or editing babel.config.js / metro.config.js.

bun run start -- -c

If that doesn't do it, reinstall and clear Expo's local cache:

rm -rf node_modules .expo
bun install
bun run start -- -c

For a dev build that still misbehaves after native changes, rebuild it: bunx expo run:ios (or run:android) regenerates the native projects from config.

Still stuck?

bunx expo-doctor checks dependency versions against your Expo SDK, and bunx expo install --fix aligns them. If that's clean too, send the command, the full error and your bun run doctor output through the support form.

On this page

Get ReadyNative