ReadyNative

Pick your stack

How to choose one option per category - what each choice costs you and where the full comparison lives.

Hey - this is the page I'd read before running bun run setup. Seventeen categories, one answer each. By the end you'll know which answers matter for your app and which you can leave on the default.

Two questions decide a category more often than taste:

  • Does it need a dev build? storage=mmkv, ui=unistyles, payments=revenuecat|adapty, widgets=expo-widgets and remote push ship native code, so Expo Go can't run them. Everything else can - see Expo Go or a dev build.
  • Does it need keys? The service categories (auth, payments, analytics, crash, push, backend) need a dashboard and a .env entry before they do anything.

Choose carefully: unless you pass --keep-modules, setup finalizes the tree and you can't re-run it with another answer (How setup works).

Set your stack in the sidebar

Pick an option in the Your stack panel at the top of the sidebar and every page on this site switches to it: tutorial code samples change, the Features tree hides the options you didn't pick, and the option pages of a category outside your stack tell you so.

Two shortcuts:

  • bun run setup and bun run doctor both print https://readynative.app/docs/?stack=ui:tamagui,auth:supabase,…. Open that link and the docs already match your tree.
  • The panel's Import .readynative.json button reads the file setup wrote and does the same from a local checkout.

The categories

Each heading links to the category's Features page, where every option has its own Setup / Usage / Gotchas guide. Stack comparison puts every option of every category in one generated table, with Expo Go verdicts, requires / conflicts rules and the env keys each one needs.

UI

NativeWind 4 (stable, Tailwind 3) is the default and what I'd keep. NativeWind 5 is one flag away - --ui nativewind5, labelled "RC · Tailwind 4" in the picker because it is still a release candidate (5.0.0-rc.0); pick it if you want Tailwind 4 today. Pick Tamagui for its compiler and theme system, Unistyles for a C++ StyleSheet with themes and breakpoints (dev build), stylesheet for no style engine at all. Whichever you pick, screens use the same primitives from @/components/ui - see Styling.

Data

TanStack Query for REST, Apollo if your backend is GraphQL, SWR if you want the smallest stale-while-revalidate hook, none for plain fetch. With none you can still add any of them by hand later with bunx expo install.

State

Zustand by default, Jotai if you think in atoms, none for useSyncExternalStore stores only. Both libraries persist through the storage adapter, so they require a real storage option.

Storage

expo-sqlite/kv-store gives you sync and async key/value on SQLite in Expo Go. MMKV is faster but native (dev build). AsyncStorage is the async-only community standard. Auth sessions, i18n and persisted stores all sit on top of this choice.

Forms

React Hook Form with a zod resolver, wrapped as Form + Field over the kit's Input; or none and controlled inputs with useState.

i18n

i18next or Lingui, with English, Spanish, Russian, Chinese (Simplified), Portuguese and Arabic bundled either way. Arabic is right-to-left: picking it mirrors the whole layout and restarts the app (in a dev build - Expo Go resets the direction). With none, i18n.t and useT return the English key, so screens keep compiling.

Auth

Pro

Supabase gives you accounts plus a Postgres database behind them; Clerk gives you a hosted user system with email-code verification; Better Auth runs on your own API routes (so it requires backend=api-routes). @/lib/auth is the same API in all three - auth.useSession(), auth.signOut() - and with none it reports signed-out forever.

Payments

Pro

RevenueCat and Adapty handle StoreKit and Play Billing for you but need a dev build. Stripe Checkout runs in Expo Go because the purchase happens on the web, through your API routes. payments.useEntitlements() is the shim in all three cases.

Analytics

Pro

PostHog (analytics plus feature flags) or Amplitude. With none, analytics.track / identify / screen are no-ops you can leave in your code.

Crash reporting

Pro

Sentry, or nothing. In Expo Go you get JS errors only; native crashes need a dev build.

Push

Pro

expo-notifications covers local notifications in Expo Go and remote push in a dev build. It requires a real storage option to keep the token.

Backend

Pro

Expo Router +api.ts routes with src/server helpers, deployable to EAS Hosting - and the prerequisite for Better Auth and Stripe. Or none if your backend lives elsewhere. Not sure whether you need one at all? Read Do I need a backend? first.

Onboarding

on adds a three-slide intro at /onboarding that redirects until it is completed; off opens straight into the tabs.

Location

expo-location gives screens the user's position and a place name, asking for "while using the app" permission only; it runs in Expo Go. location.getCurrentPosition() resolves null instead of throwing, whichever option you pick. Pick none if no screen needs it: no permission prompt and no purpose string for App Review to question.

Widgets

expo-widgets adds an iOS home-screen widget written in TypeScript with @expo/ui SwiftUI views, fed with widgets.update({ title, value, subtitle, symbol }). It needs a dev build. none keeps the same call as a no-op, so you can wire it now and turn it on later.

consent shows a sheet in the EU/EEA, UK, Switzerland, Canada and Brazil (or everywhere, with privacy.askEverywhere) that asks before analytics and crash reporting start; none treats everyone as consented. You rarely pick it by hand: setup selects consent whenever an analytics or crash module is in, and none when neither is. Pass --consent none only if you never ship to those regions.

Testing

Jest with jest-expo and React Native Testing Library, including tests for the stores, the theme and the UI kit. none removes the runner and every __tests__ folder - including the ones modules would have brought.

Not sure? Start from a preset

minimal, default and saas are three complete answers; override single categories on top of them. The table is in Quickstart, and bun run setup --dry-run prints the full plan - selection, Expo Go verdict, dependency delta, files touched - without changing anything.

On this page

Get ReadyNative