Supabase
The Open Source Firebase Alternative Built on PostgreSQL
What is Supabase?
Supabase provides all the backend features you need to build a product, without the need to set up and manage a traditional server. Under the hood, it runs a full and real PostgreSQL relational database, providing advanced security with Row Level Security (RLS) and native vector search support.
Key Features for Your Stack
ποΈ Real & Scalable PostgreSQL
Full access to SQL relational tables, triggers, functions, and high-performance extensions like `pgvector`.
π Production-Ready Auth
Email and password login, Magic Links, passwordless authentication, and multiple OAuth providers (Google, GitHub, Apple).
π Secure Storage
Host and serve user files like media, photos, and documents with built-in CDN and advanced access rules.
β‘ Automatically Generated APIs
Write database tables and instantly receive secure, high-speed REST and GraphQL APIs compliant with RLS.
Example Relational Modeling
Here is a classic example of setting up a SQL table with Row Level Security enabled so users can only read their own profiles:
-- Create a table for user profiles linked to Supabase Auth.users
create table public.profiles (
id uuid references auth.users not null primary key,
updated_at timestamp with time zone,
username text unique,
full_name text,
avatar_url text,
website text,
constraint username_length check (char_length(username) >= 3)
);
-- Enable Row Level Security (RLS)
alter table public.profiles enable row level security;
-- Create policy for public read access
create policy "Public profiles are viewable by everyone." on public.profiles
for select using (true);
-- Create policy for users to update their own profiles
create policy "Users can update their own profiles." on public.profiles
for update using (auth.uid() = id);
Consuming Data with Supabase JS/TS SDK
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
// Fetch profile for logged-in user
async function getProfile(userId) {
const { data, error } = await supabase
.from('profiles')
.select('username, full_name, website')
.eq('id', userId)
.single()
if (error) throw error
return data
}