How to Set Up Supabase Auth in React Native

Supabase Auth in React Native with Expo: email, OAuth, magic link. Cookie-based sessions with @supabase/ssr. The setup that actually works in production.

Learn/How to Set Up Supabase Auth in React Native
beginner15 minutes

How to Set Up Supabase Auth in React Native

Supabase Auth in React Native. Email, OAuth, magic link. Production setup in 15 minutes.

Prerequisites

Supabase projectReact Native or Next.js project

The Right Way

There are two Supabase clients. One works. One doesn't.

  • @supabase/ssrUse this. Cookie-based sessions. Works on server and client.
  • @supabase/supabase-js createClientNever use this for auth. Uses localStorage. Doesn't work server-side.

I wasted 4 hours on my first app using the wrong client. Don't repeat my mistake.

Setup

1. Install

npx expo install @supabase/supabase-js @supabase/ssr

2. Create the Browser Client

// lib/supabase-browser.ts
import { createBrowserClient } from '@supabase/ssr';

export const supabase = createBrowserClient(
  process.env.EXPO_PUBLIC_SUPABASE_URL!,
  process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY!
);

3. Create the Server Client

For Next.js API routes or server actions:

// lib/supabase-server.ts
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';

export async function getSupabaseServerClient() {
  const cookieStore = await cookies();
  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() { return cookieStore.getAll(); },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) =>
            cookieStore.set(name, value, options)
          );
        },
      },
    }
  );
}

4. Email/Password Sign Up

const { data, error } = await supabase.auth.signUp({
  email: 'user@example.com',
  password: 'securepassword',
});

5. OAuth (Google, Apple)

const { data, error } = await supabase.auth.signInWithOAuth({
  provider: 'google',
  options: {
    redirectTo: 'yourapp://auth/callback',
  },
});

For OAuth to work with Expo, you need deep linking configured in app.json:

{
  "expo": {
    "scheme": "yourapp"
  }
}

6. Token Handler Component

After OAuth redirect, the URL contains tokens that need to be converted to cookies:

// TokenHandlerInBrowser.tsx
import { useEffect } from 'react';
import { supabase } from './supabase-browser';

export function TokenHandlerInBrowser() {
  useEffect(() => {
    supabase.auth.onAuthStateChange((event, session) => {
      // Session is automatically managed via cookies
    });
  }, []);
  return null;
}

Include this component in every layout that needs auth.

The Critical Rule

Server-side: always use await getSupabaseServerClient()

// Correct
const supabase = await getSupabaseServerClient();
const { data: { user } } = await supabase.auth.getUser();

// Wrong — will not have auth context
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(url, key);

RLS Policies

Once auth is set up, enable Row Level Security on your tables:

ALTER TABLE your_table ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Users can read own data"
  ON your_table FOR SELECT
  USING (auth.uid() = user_id);

This ensures users can only access their own data, regardless of what the application code does.

Related

Or let AI App Factory handle this for you.

Everything in this guide is already pre-configured in AI App Factory. 11 AI agents automate the rest.

AI App FactoryLearnHow to Set Up Supabase Auth in React Native