FreeMIT licenseExpo SDK 58TypeScript

The free React Native auth template with four swappable backends

Stop rebuilding login screens for every app. Get sign in, sign up, password reset and protected routes for Expo SDK 58, ready to run. Use Firebase, Supabase, Appwrite or local SQLite, and switch between them by changing one env var.

git clone https://github.com/developermill22/expo-auth-starter.git
screens ready to use
7

screens ready to use

auth backends
4

auth backends

commands to run
3

commands to run

free, MIT licensed
$0

free, MIT licensed

Expo Auth Starter screenshot 1

// Overview

A free Expo login and sign-up template

Most mobile apps need sign in, sign up, password reset and a protected area before any real feature gets built. Expo Auth Starter gives you all of that, already wired up, for Expo SDK 58 with Expo Router and strict TypeScript.

What makes it different is the plug-in layer. Every backend implements one small AuthAdapter interface. Screens, hooks and the session store only talk to that interface, never to a vendor SDK. So you can start a prototype on offline SQLite today, move to Supabase next month, and the UI code does not change.

It runs in Expo Go out of the box. The default provider is local SQLite, so a fresh clone works with zero accounts, keys or cloud setup.

// Why use it

Expo Auth Starter vs. building auth from scratch

Auth looks small until you build it: form validation, error messages for every SDK, session restore, redirects, dark mode and accessibility. Here is what the template already handles for you.

TaskFrom scratchWith this template
Login, sign-up and reset screensDesign and code each one7 screens included
Change auth providerRewrite screens and stateChange one env var
Protected routesHand-written redirectsExpo Router guards
Session restore on launchEasy to get a login-screen flashSplash held until ready
Error messagesDifferent for every SDKOne friendly set
Dark mode and accessibilityOften left for laterBuilt in, WCAG AA
Try it without a backendSet up a cloud project firstOffline SQLite by default

// Features

Features of this Expo authentication template

Pluggable backends

Firebase, Supabase, Appwrite and local SQLite ship in the box. Only the selected SDK is loaded at runtime.

Protected routes

Uses Expo Router's Stack.Protected guards. Signed-out users can't reach the app area, and signed-in users skip the auth screens.

Session restore

The splash screen stays up until the session is known, so users never see a flash of the sign-in screen on launch.

Live session sync

Token expiry or a remote sign-out on Firebase and Supabase updates the app state right away.

One error language

Every SDK's errors map to one AuthError type with friendly copy, like "An account with this email already exists."

Capability-aware UI

Each adapter declares what it can do. Flows the backend can't support, such as reset emails, are hidden automatically.

Helpful setup screen

Missing env vars show a readable screen that lists exactly which keys to set, instead of an SDK crash.

Accessible by default

Light and dark themes with WCAG AA contrast, 44px+ touch targets, labelled inputs, keyboard "next" chaining and password show/hide.

// Screens

React Native login and sign-up screens included

ScreenWhat it doesFile
WelcomeLanding screen for signed-out users. Shows which auth provider is active.src/app/(auth)/welcome.tsx
Sign inEmail and password with show/hide. "Forgot password?" appears only if the backend supports it.src/app/(auth)/sign-in.tsx
Sign upName, email, password and confirm, validated with zod as you type.src/app/(auth)/sign-up.tsx
Forgot passwordPre-fills the email from sign in. The confirmation never reveals whether an account exists.src/app/(auth)/forgot-password.tsx
Confirm your emailShown after sign-up when the backend requires email confirmation, like Supabase.src/app/(auth)/check-email.tsx
Home (protected)Shows the session user and a verify-email notice when needed.src/app/(app)/index.tsx
ProfileEdit your display name and sign out. Signing out clears all cached data.src/app/(app)/profile.tsx

Forms use react-hook-form with zod schemas. New passwords need at least 8 characters with one letter and one number.

// Backends

Firebase, Supabase, Appwrite or SQLite auth

Set EXPO_PUBLIC_AUTH_PROVIDER in .env, fill in that provider's keys, then restart with npx expo start -c.

ProviderValueReset emailVerificationSetup note
Local SQLitesqliteNoNoOffline, on-device accounts. No setup needed.
FirebasefirebaseYesYesEnable Email/Password in Console → Authentication.
SupabasesupabaseYesYesAdd authstarter://** to Auth → Redirect URLs.
AppwriteappwriteYes*YesRegister your Android/iOS platform with the bundle ID.

* Appwrite reset emails need EXPO_PUBLIC_APPWRITE_RECOVERY_URL. Leave it empty and the "Forgot password?" link is hidden.

// Get started

How to set up Expo authentication in 3 commands

  1. 1

    Download or clone

    Grab the ZIP from GitHub or clone the repo, then install packages.

    Terminal
    git clone https://github.com/developermill22/expo-auth-starter.git
    cd expo-auth-starter
    npm install
  2. 2

    Create your .env

    The example file defaults to local SQLite, so nothing else is needed to try it.

    Terminal
    cp .env.example .env
  3. 3

    Start the app

    Open it in Expo Go on your phone, or in an iOS simulator, Android emulator or the browser.

    Terminal
    npx expo start
  4. 4

    Switch to a cloud backend (optional)

    Change the provider, paste that provider's public keys, and restart with a clean cache.

    Terminal
    # .env
    EXPO_PUBLIC_AUTH_PROVIDER=supabase
    EXPO_PUBLIC_SUPABASE_URL=https://xyz.supabase.co
    EXPO_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
    
    npx expo start -c

// Architecture

How the pluggable auth layer works

App code only talks to AuthAdapter. Actions run as TanStack Query mutations, update a Zustand store on success, and the root layout's Stack.Protected guards redirect between (auth) and (app) when the session changes.

src/auth
src/auth/
  types.ts        AuthAdapter interface + AuthUser shape  ← the contract
  errors.ts       AuthError + friendly messages
  config.ts       env reading + "missing keys" validation
  index.ts        registry: provider name → lazy-loaded adapter
  adapters/
    sqlite.ts     expo-sqlite + expo-crypto + expo-secure-store
    firebase.ts   firebase JS SDK (AsyncStorage persistence)
    supabase.ts   @supabase/supabase-js (AppState auto-refresh)
    appwrite.ts   react-native-appwrite

// Use cases

Who this React Native auth starter is for

Indie makers & MVPs

Ship the login on day one

Skip a week of auth plumbing. Start on local SQLite with no accounts, then point at a real backend when you have users.

sqlite → supabase
Agencies & freelancers

One codebase for every client

Client A uses Firebase, client B already pays for Supabase. Reuse the same screens and switch the provider per project.

firebase | supabase | appwrite
Teams migrating backends

Move off a vendor safely

Moving from Firebase to Supabase or self-hosted Appwrite? Swap the adapter and keep your UI and navigation untouched.

firebase → supabase
Offline-first apps

Accounts without a server

Field tools, kiosks, journals and local-only apps can keep salted, hashed accounts on the device with expo-sqlite and SecureStore.

sqlite
Companies with their own API

Plug in a custom REST backend

Write one adapter file for your API, map its errors to AuthError, register it, and every screen works with it.

rest (your adapter)
Learners & hackathons

See clean auth architecture

A small, commented codebase that shows Expo Router guards, Zustand, TanStack Query and zod working together.

any provider

// Customize

Customize the template for your app

Add your own backend

  1. 1

    Create the adapter

    Add src/auth/adapters/rest.ts that exports createRestAdapter(): AuthAdapter.

  2. 2

    Name it

    Add 'rest' to AUTH_PROVIDERS in types.ts.

  3. 3

    Register it

    Add one line to the registry in src/auth/index.ts.

  4. 4

    Select it

    Set EXPO_PUBLIC_AUTH_PROVIDER=rest. No screen changes needed.

Use the session anywhere

tsx
import { useCurrentUser } from '@/store/auth-store';
import { useSignOut } from '@/hooks/use-auth';

const user = useCurrentUser();   // AuthUser | null
const signOut = useSignOut();    // signOut.mutate()

Before you ship

  • Rename com.example.authstarter and the authstarter URL scheme in app.json.
  • Only put public client keys in EXPO_PUBLIC_* vars. They are bundled into the app.
  • Swap the placeholder logo mark on the welcome screen for your own.
  • Re-skin the whole app by editing the semantic palette in src/theme/index.ts.

// FAQ

Expo auth template FAQ

Is the Expo Auth Starter really free?

Yes. The full source is on GitHub under the MIT license. Use it in personal and commercial apps.

Does it work in Expo Go?

Yes. All four backends use JavaScript SDKs or modules bundled with Expo Go. If you later add a native auth SDK, such as Google or Apple sign-in, you'll need a development build with npx expo run:android or eas build --profile development.

Does it include Google, Apple or social login?

Not yet. This template covers email and password. Social sign-in can be added inside an adapter without touching the screens.

How are SQLite passwords stored?

As a salted, iterated SHA-256 hash with a random salt per user. That's fine for device-only data. If you ever sync those accounts to a server, hash on the server with argon2 or bcrypt.

Can I get an access token for my own API?

Yes. Read the backend's token inside the adapter, such as supabase.auth.getSession() or auth.currentUser.getIdToken(), and expose it with a getAccessToken() method.

Does it run on the web?

The project includes react-native-web, so npm run web starts it in the browser. It is built and tuned for iOS and Android first.

Tech Stack

ExpoReact NativeTypeScriptExpo RouterFirebaseSupabaseAppwriteexpo-sqliteZustandTanStack QueryReact Hook FormZod

Skip the auth boilerplate. Start on your features.

Free and open source. If it saves you time, a GitHub star helps other developers find it.

templateAuthenticationSDK 58

Expo Auth Starter

A free React Native auth template for Expo SDK 58: sign in, sign up, password reset and protected routes, with Firebase, Supabase, Appwrite or local SQLite behind one env var.

View source

Free License

Personal and commercial use

Free
  • Use in 1 personal project
  • Lifetime access to updates
  • Email support
  • Remove attribution
  • Commercial use included
Get it on GitHub
Expo SDK
58
React Native
0.88
React
19.3
Language
TypeScript 6 (strict)
Navigation
Expo Router
State
Zustand 5
Data
TanStack Query 5
Forms
RHF + zod 4
Platforms
iOS · Android · Web
Expo Go
Supported