Auth
Auth for an Expo app, compared: Supabase Auth, Clerk, Better Auth, or none - Expo Go support and what each option installs.
Hey - here's how auth works in ReadyNative.
This category owns everything about the signed-in user: the sign-in, sign-up and reset screens under src/app/(auth), the redirect hook that decides where a signed-out person lands, and the Account card in Settings.
@/lib/auth always exists, whichever option you pick: auth.useSession() and auth.signOut() read the same in every one of them, and auth/none is a no-op that reports a signed-out session. Screens you write against the shim keep working when you switch options.
Pick Supabase if you also want a Postgres database and row-level security behind the same account - it's the cheapest path from zero to a real backend. Pick Clerk if you'd rather buy user management outright: hosted accounts, a good dashboard, organizations, and a code-based sign-up flow that's already wired here. Pick Better Auth if the user table has to be yours - it runs on your own API routes (backend/api-routes is required), with no third-party dashboard and no per-user pricing, in exchange for owning the database and the mail provider.
This category is part of ReadyNative Pro.
Options
One option per category - --auth <option> picks it:
bun run setup --auth supabase| Option | Label | Expo Go | Hint |
|---|---|---|---|
supabase | Supabase Auth (default) | yes | email+password, Apple (native), Google (OAuth) · session on the storage adapter · Expo Go OK |
clerk | Clerk | yes | email+code verification, Apple (native), Google (SSO) · @clerk/expo · Expo Go OK for JS flows |
better-auth | Better Auth | yes | self-hosted on the API routes · email/password + Apple/Google · Expo Go OK |
none | No auth | yes | auth.useSession() shim returns signed-out, signOut resolves |