DEV Community

Cover image for Supabase with React Native: A Complete Setup Guide
PEAKIQ
PEAKIQ

Posted on • Originally published at peakiq.in

Supabase with React Native: A Complete Setup Guide

Originally published on PEAKIQ

Source: https://www.peakiq.in/blog/how-to-set-up-supabase-in-a-bare-react-native-app



This guide covers everything needed to integrate Supabase into a bare React Native project:

  • Installing Supabase and required polyfill packages
  • Setting up polyfills for Node and Web APIs
  • Securely persisting auth sessions using react-native-keychain
  • Querying data from your Supabase tables

Works with React Native 0.80+ and Supabase JS v2+ (2025)


Prerequisites

  • Node.js and React Native CLI installed
  • A Supabase account and project
  • A bare React Native app (not using Expo)

Step 1 — Install Supabase and Required Packages

Install the core libraries:

npm install @supabase/supabase-js react-native-get-random-values react-native-url-polyfill base-64 react-native-keychain
Enter fullscreen mode Exit fullscreen mode

Then install iOS pods:

npx pod-install
Enter fullscreen mode Exit fullscreen mode

Step 2 — Create Polyfills for Node-like APIs

React Native does not include Node.js globals like Buffer, process, btoa, or atob. Create a polyfill file to patch them.

Create src/polyfills.ts:

// src/polyfills.ts

import 'react-native-url-polyfill/auto';
import 'react-native-get-random-values';
import { decode, encode } from 'base-64';
import { Buffer } from 'buffer';
import process from 'process';

// Base64 support
if (!global.btoa) global.btoa = encode;
if (!global.atob) global.atob = decode;

// Buffer and process globals
if (!global.Buffer) global.Buffer = Buffer;
if (!global.process) global.process = process;
Enter fullscreen mode Exit fullscreen mode

Then import this file at the very top of index.ts or index.js, before any other import:

// index.ts

import './src/polyfills';
import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';

AppRegistry.registerComponent(appName, () => App);
Enter fullscreen mode Exit fullscreen mode

The polyfill import must come first. Placing it after other imports can cause subtle runtime errors with URL parsing or random value generation.


Step 3 — Secure Auth Storage Using Keychain

Supabase needs a storage adapter to persist the auth session between app launches. Using react-native-keychain stores tokens in the iOS Keychain and Android EncryptedSharedPreferences — far safer than AsyncStorage.

Create src/utils/SecureStorage.ts:

// src/utils/SecureStorage.ts

import * as Keychain from 'react-native-keychain';

export const SecureStorage = {
  getItem: async (key: string) => {
    const credentials = await Keychain.getGenericPassword({ service: key });
    return credentials ? credentials.password : null;
  },
  setItem: async (key: string, value: string) => {
    await Keychain.setGenericPassword('user', value, { service: key });
  },
  removeItem: async (key: string) => {
    await Keychain.resetGenericPassword({ service: key });
  },
};
Enter fullscreen mode Exit fullscreen mode

Step 4 — Set Up the Supabase Client

Create src/lib/supabase.ts and pass SecureStorage as the auth storage adapter:

// src/lib/supabase.ts

import { createClient } from '@supabase/supabase-js';
import { SecureStorage } from '../utils/SecureStorage';

const supabaseUrl = 'https://your-project.supabase.co';
const supabaseAnonKey = 'your-anon-key'; // Supabase dashboard > Settings > API

export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
  auth: {
    storage: SecureStorage,
    autoRefreshToken: true,
    persistSession: true,
    detectSessionInUrl: false, // Not needed in mobile apps
  },
});
Enter fullscreen mode Exit fullscreen mode

Step 5 — Test a Supabase Query

Import the client and run a query to confirm everything is wired up correctly:

import { supabase } from './lib/supabase';

const fetchData = async () => {
  const { data, error } = await supabase.from('test').select('*');
  if (error) {
    console.error('Supabase Error:', error.message);
  } else {
    console.log('Data:', data);
  }
};
Enter fullscreen mode Exit fullscreen mode

Summary

Step What you set up
Install packages supabase-js, polyfills, react-native-keychain
Polyfills Buffer, process, btoa/atob, URL support
Secure storage Keychain adapter for iOS and Android
Supabase client createClient with secure storage and auto token refresh
Query .from('table').select('*')

Troubleshooting

No network on iOS 18.4+

If Supabase requests are silently failing on the iOS simulator or device running iOS 18.4+, use Proxyman to inspect network traffic and confirm requests are leaving the device correctly. This is a known iOS 18.4 simulator networking quirk.


Top comments (0)