FAQ
Expo Go vs dev builds, changing modules after setup, adding modules, className, web, previews, env keys.
Expo Go or a dev build?
Every module runs in Expo Go except the five that ship native code:
storage=mmkv, ui=unistyles, payments=revenuecat, payments=adapty and remote push with
push=expo-notifications. bun run setup prints the verdict for your selection
(Expo Go: yes / NO - a dev build is required), and each module page shows an Expo Go badge.
Expo Go or a dev build explains why and walks you through making
one.
Can I change a module after setup?
Only if modules/ still exists. setup deletes it unless you passed --keep-modules; with the
folder present, this re-resolves the plan, copies the new module, removes the old one's files and
regenerates providers and env:
bun run setup --payments stripe --backend api-routes --yes --keep-modulesA finalized tree can't switch: setup is a stub once modules/ is gone, and copying the folder
back from upstream doesn't restore the module system. Clone a fresh copy of your tier repo, run
setup there with the new selection, and port your own code (screens, stores,
readynative.config.ts) across. Removing a module by hand is possible - every module page has
a Remove it section listing its files, dependencies and env keys. Pulling fixes into a
finalized tree is covered in Update from upstream.
How do I add my own module?
This needs modules/, so it works in a tree set up with --keep-modules:
bun run gen module analytics mixpanelcreates modules/analytics/mixpanel/{module.json,files/,docs.md}. Then:
- Fill
module.json:label,hint,expoGo,dependencies,files[](root-relative, mirrored underfiles/),providers,env(every key with adocsUrl, secrets asserver: true),requires/conflicts,postSetup. The schema is zod inscripts/lib/schema.ts; every field exceptid/category/labelhas a default. - For a service category, implement the shim contract from
src/lib/shims/<category>.tsunderfiles/src/lib/<category>.tswith the same export names, so core code keeps importing@/lib/<category>. - Add the option to
CATALOGinscripts/lib/catalog.ts(first entry = default). - Write
docs.md(what it adds, keys, dashboards, a "Manual E2E checklist"). - Apply it and check it:
bun run setup --analytics mixpanel --yes --keep-modules, thenbun run typecheck,bun run lintandbunx expo export -p ios -p android.
The full contract is in the module spec.
Why is there no className on the kit's primitives?
Because three of the five UI stacks have no Tailwind. The primitives' props are token-typed
(p={4}, bg="card", radius="lg"), and style is the single escape hatch, so the same
screens compile on nativewind4, nativewind5, tamagui, unistyles or stylesheet. Inside
a NativeWind kit you can use classes freely, and once setup has finalized your tree the kit in
src/components/ui is plain code you own - add className if you want it. See
Styling.
Does it run on the web?
app.config.ts sets web.output: "static" ("server" with backend=api-routes), and
bun run web starts expo start --web. Web is best-effort: the checks I run before each release
export iOS and Android only. NativeWind and Tamagui render fine on web; unistyles is
native-first (its web shell in src/app/+html.tsx is not a gate); RevenueCat and native push
have no web path. expo export -p web ships the public/ folder (including .well-known/ from
gen:links) as-is, which is enough to host universal-link files.
The Free tier ships without a web script and without react-dom and react-native-web, so it
doesn't run on the web out of the box. The web block in app.config.ts is still there; add
the two packages, then start the web target:
bunx expo install react-dom react-native-web
bunx expo start --webWhy NativeWind 4 and not NativeWind 5 as the default?
NativeWind 5 is still a release candidate (nativewind@5.0.0-rc.0 with
react-native-css@3.1.0-rc.0), so the default is the stable release: NativeWind 4.2 on
Tailwind 3 (nativewind@4.2.7), which the committed tree and every preset use and which gets
the most testing. The theme is generated as HSL triples into tailwind.config.js. Want
Tailwind 4 now? bun run setup --ui nativewind5 - labelled "RC · Tailwind 4" in the picker -
gives you the same primitives on NativeWind 5, and adds the lightningcss override to
package.json that NativeWind 5 needs. When NativeWind 5 ships a stable release, it becomes
the default in an update.
Tamagui and the React Compiler
experiments.reactCompiler is on for every stack, including Tamagui 2 with the optimising
compiler: tsc, jest and expo export pass with both enabled. Only device runs can prove the
Reanimated press animations; if they misbehave, set
"app": { "expo": { "experiments": { "reactCompiler": false } } } in
modules/ui/tamagui/module.json (or your .readynative.json → modules.app) and rebuild. The
first Tamagui build prints a few benign [tamagui] skipped loading … warning-001 lines and
writes a .tamagui/ cache folder (gitignored).
What does bun run doctor check?
Your selection, the env keys your modules need, the placeholders in readynative.config.ts
(and that it loads under Node), your EAS login, the app icon, the native toolchains when a module
needs them, and the bun and Node versions. Store and release placeholders are listed under
"Before you ship" as warnings, so a fresh setup exits 0; bun run doctor --store turns them
into failures. Every row is explained in Doctor.
Where do API keys go?
In .env at the repo root (gitignored); .env.example is generated with every key your
selection needs and a # docs: link per key. EXPO_PUBLIC_* keys are bundled into the app, and
a missing one degrades its module ("Configure Supabase") instead of crashing. Keys without the
prefix (STRIPE_SECRET_KEY, BETTER_AUTH_SECRET, …) are server-only: they're never written to
src/lib/env.ts, so they can't leak into the bundle. For EAS builds, the same keys go in EAS
environment variables. Environment variables has every key and
the visibility each kind needs on EAS.
How long do updates last?
For as long as ReadyNative is maintained - every paid license includes lifetime updates, and your GitHub access stays. License → Lifetime updates says what "lifetime" means, and Update from upstream shows how to pull a release in.
Can I get a refund?
No refunds once you have access to the repo, except where the law requires otherwise; Polar, the merchant of record, handles those. See License → Refunds.
Why is setup one-way?
So the shipped app is a plain Expo project: no runtime module registry, no unused adapters,
no dependencies for stacks you didn't pick. Keeping modules/ around (--keep-modules) costs
nothing but disk space and keeps the door open for changes and upstream merges. How setup
works has what finalizing changes.
How do I get help?
Through the support form on the landing site - questions before you buy, bugs, invoices, extra seats. That's the only channel: there's no support email, so nothing gets lost in a mailbox. Paid but no repo? Open the customer-portal link in Polar's receipt email and connect your GitHub account (Get access has the steps). Still stuck? Pick "Paid, no repo access" on the support form and leave the email you paid with.