Supabase CLI Integration
This guide shows how to integrate Supabase with a React Native (Expo, TypeScript) project using the official
todos example.
Install Supabase CLI
Install globally:
brew install supabase/tap/supabase
# or
npm install -g supabase
Check version:
supabase --version
Initialize Supabase Project
supabase init
# or
npx supabase init
This creates a supabase/ folder with:
migrations/: This is where your SQL migration files for table and column changes will go.seed.sql: This is where you can put SQL commands to seed initial data into your database.config.toml: This is the configuration file for your Supabase project.
Start Local Supabase (Docker)
Pre-requisite: Docker installed.
supabase start
This runs PostgreSQL, Studio, Auth, Realtime, and Storage locally by using Docker.
Check Supabase Status
You can inspect the local services with:
supabase status
This shows useful connection details:
- API URL → REST API base endpoint for client requests
- GraphQL URL → GraphQL endpoint
- S3 Storage URL → Storage service endpoint
- Database URL → PostgreSQL connection string (use in psql/clients)
- Studio URL → Local Supabase Studio (browser UI)
- Mailpit URL → Local email testing server (see passwordless links)
- Publishable key → Public (client-side) key for local dev (not a real JWT)
- Secret key → Private (server-side) key for admin operations
- S3 Access Key / Secret Key → Credentials for accessing storage
- S3 Region → Dummy region for local S3 storage
Stop Local Database
To stop:
supabase stop
Stop the local Supabase Docker containers without taking a backup:
supabase stop --no-backup
- Use this if you want to cleanly shut down local services.
- The
--no-backupflag prevents creating a dump before stopping.
Database Setup & RLS Policies
-
You can follow the Database Setup guide to create a
todostable with a migration and add some initial data with seeds. -
You can follow the RLS & Policies guide to add Row Level Security policies.
Environment Variables (Expo)
Create a .env file in your project:
- local (
.env.local):
EXPO_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
EXPO_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIs...
Local Supabase keys are not valid JWTs. You can get anon key from local dashboard under Settings → API by using Studio URL.
- prod (
.env.production):
EXPO_PUBLIC_SUPABASE_URL=https://your-project-ref.supabase.co
EXPO_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIs...
Restart Expo:
npx expo start -c
Supabase Client (TypeScript)
Install Supabase SDK
npm install @supabase/supabase-js
Setup Supabase Client
utils/supabase.ts:
import {createClient} from '@supabase/supabase-js';
export type Todo = {
id: number;
title: string;
is_complete: boolean;
inserted_at: string;
};
export type Database = {
public: {
Tables: {
todos: {
Row: Todo;
Insert: Omit<Todo, 'id' | 'inserted_at'>;
Update: Partial<Omit<Todo, 'id'>>;
};
};
};
};
const SUPABASE_URL = process.env.EXPO_PUBLIC_SUPABASE_URL as string;
const SUPABASE_ANON_KEY = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY as string;
if (!SUPABASE_URL || !SUPABASE_ANON_KEY) {
throw new Error('Missing Supabase environment variables');
}
export const supabase = createClient<Database>(
SUPABASE_URL,
SUPABASE_ANON_KEY
);
React Native Example (Todos Screen)
todos.tsx:
import React, {useState, useEffect} from 'react';
import {View, Text, FlatList, ActivityIndicator} from 'react-native';
import {supabase} from './utils/supabase';
import type {Todo} from './utils/supabase';
export default function TodosScreen() {
const [todos, setTodos] = useState<Todo[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const getTodos = async () => {
setLoading(true);
const {data, error} = await supabase.from('todos').select('*');
if (error) {
console.error('Error fetching todos:', error.message);
} else if (data) {
setTodos(data);
}
setLoading(false);
};
getTodos();
}, []);
if (loading) {
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<ActivityIndicator size="large" color="#2563eb"/>
</View>
);
}
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text style={{fontWeight: 'bold', fontSize: 20}}>Todo List</Text>
<FlatList
data={todos}
keyExtractor={(item) => item.id.toString()}
renderItem={({item}) => (
<Text>
{item.title} {item.is_complete ? '✅' : '⬜️'}
</Text>
)}
/>
</View>
);
}
Cloud Project Setup (Prod)
For your production environment, you need a Supabase Cloud project:
- Go to Supabase Dashboard
- Create a project
- Copy your API URL and anon key from Settings → API
Authentication for CLI
Before linking, log in with your personal access token (one-time setup):
supabase login
This will open a browser where you can get your access token from the dashboard (Account Settings → Access Tokens).
Linking Local Project to Cloud
Link your local Supabase project folder to a specific cloud project:
supabase link --project-ref your-project-ref
your-project-refis the unique identifier for your Supabase cloud project (found in project settings).
Push Local Migrations to Cloud
Once linked, you can push your local migrations to the cloud database:
supabase db push
Unlink from Cloud
If you want to disconnect your local project from the cloud:
supabase unlink
✅ Summary:
supabase login→ authenticate CLI with your Supabase account.supabase link→ connect local project to a specific cloud project.supabase db push→ apply local migrations to the cloud database.supabase unlink→ remove the link between local and cloud projects.
CI/CD Deployment
In a CI/CD pipeline (e.g., GitHub Actions, GitLab CI, Vercel, etc.), you can automate pushing migrations and deploying functions.
Generate a Personal Access Token
In the Supabase Dashboard → Account Settings → Access Tokens, create a new token.
Store this securely in your CI/CD provider as a secret environment variable:
SUPABASE_ACCESS_TOKEN=your-token
Example GitHub Actions Workflow
Create .github/workflows/deploy.yml:
name: Deploy Supabase
on:
push:
branches:
- master
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: supabase/setup-cli@v1
with:
version: latest
- run: supabase link --project-ref $SUPABASE_PROJECT_REF
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
- run: supabase db push
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
✅ With this setup:
- Every push to
masterwill link your project. - Apply new migrations automatically on the cloud database.
- No need to run
supabase loginmanually in CI/CD; the access token handles authentication.
Database Sync (Cloud ↔ Local)
Sometimes you need to synchronize your local database with the cloud (production) database for testing or development.
Pull Cloud Schema to Local
Fetch the current cloud database schema and create a migration file:
supabase db pull
- Creates a SQL file under
supabase/migrations/with the full schema. - Use this when local DB is empty, or you want to match cloud schema.
Note: This only pulls the schema, not the data.
Generate Migration from Differences
Compare your local DB with the cloud DB and create a migration for the differences:
supabase db diff -f add_new_table
- Generates a migration file in
supabase/migrations/. - Useful when you made changes locally and want to push them to the cloud.
Pull Cloud Data (Optional)
If you want existing cloud data locally for testing:
supabase db dump --data-only > supabase/seed.sql
Then reset local DB and load the data:
supabase db reset
psql "postgresql://postgres:postgres@127.0.0.1:54322/postgres" -f supabase/seed.sql
This will give you a local copy of cloud data for development/testing purposes.
✅ Summary:
db pull→ Pull cloud schema onlydb diff→ Generate migration from local vs cloud differencesdb dump --data-only→ Pull cloud data
Common CLI Commands
supabase init # initialize project
supabase start # start local containers
supabase stop # stop local containers
supabase db reset # reset DB and reapply migrations
supabase db diff -f <name> # create migration from schema changes
supabase link --project-ref <ID> # link local project to cloud
supabase db push # push migrations to cloud
Recommended Workflow
- Use Cloud Supabase for the app → for Auth, Realtime, RLS, and proper anon keys.
- Use Local Docker Supabase for DB dev → for schema changes, migrations, seeds.
- Deploy to production via
supabase db pushin CI/CD.
References
- Supabase Documentation – Official docs for all Supabase features
- Supabase GitHub – Source code, CLI, and examples
- Supabase CLI Reference – Detailed commands and flags
- Supabase Expo Integration – Using Supabase with React Native / Expo
- Youtube Video – How to Run Supabase Project Locally with Supabase CLI and Docker