Supabase is an open-source Firebase alternative with a real PostgreSQL database. Auth, real-time subscriptions, storage, edge functions — all built on open-source tools.
Why Supabase?
- Real PostgreSQL — not a document database pretending to be SQL
- Row-Level Security — database-level auth policies
- Real-time — subscribe to database changes via WebSocket
- Free tier — 500MB database, 1GB storage, 50K monthly active users
- Self-hostable — Docker Compose or Kubernetes
Quick Start
npm install @supabase/supabase-js
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
'https://YOUR_PROJECT.supabase.co',
'YOUR_ANON_KEY'
);
CRUD Operations
// Insert
const { data, error } = await supabase
.from('posts')
.insert({ title: 'Hello', content: 'World', user_id: userId })
.select();
// Select
const { data: posts } = await supabase
.from('posts')
.select('*, author:users(name, avatar)')
.eq('status', 'published')
.order('created_at', { ascending: false })
.limit(10);
// Update
const { data } = await supabase
.from('posts')
.update({ title: 'Updated' })
.eq('id', postId)
.select();
// Delete
const { error } = await supabase
.from('posts')
.delete()
.eq('id', postId);
Auth
// Sign up
const { data, error } = await supabase.auth.signUp({
email: 'alice@example.com',
password: 'secure-password',
});
// Sign in
const { data } = await supabase.auth.signInWithPassword({
email: 'alice@example.com',
password: 'secure-password',
});
// OAuth
const { data } = await supabase.auth.signInWithOAuth({
provider: 'github',
});
// Get user
const { data: { user } } = await supabase.auth.getUser();
// Sign out
await supabase.auth.signOut();
Real-Time Subscriptions
const channel = supabase
.channel('posts-changes')
.on('postgres_changes', {
event: '*',
schema: 'public',
table: 'posts',
}, (payload) => {
console.log(payload.eventType); // INSERT, UPDATE, DELETE
console.log(payload.new); // New row data
console.log(payload.old); // Old row data
})
.subscribe();
// Filter changes
supabase
.channel('my-posts')
.on('postgres_changes', {
event: 'INSERT',
schema: 'public',
table: 'posts',
filter: `user_id=eq.${userId}`,
}, handleNewPost)
.subscribe();
Storage
// Upload
const { data, error } = await supabase.storage
.from('avatars')
.upload(`${userId}/avatar.png`, file);
// Get public URL
const { data: { publicUrl } } = supabase.storage
.from('avatars')
.getPublicUrl(`${userId}/avatar.png`);
// Download
const { data, error } = await supabase.storage
.from('avatars')
.download(`${userId}/avatar.png`);
Row-Level Security
-- Users can only read published posts
CREATE POLICY "Public posts" ON posts
FOR SELECT USING (status = 'published');
-- Users can only edit their own posts
CREATE POLICY "Own posts" ON posts
FOR UPDATE USING (auth.uid() = user_id);
-- Users can only insert as themselves
CREATE POLICY "Insert own" ON posts
FOR INSERT WITH CHECK (auth.uid() = user_id);
Need to populate your Supabase database with web data? Check out my Apify actors for web scraping, or email spinov001@gmail.com for custom data pipelines.
Supabase, Firebase, or PocketBase — which BaaS do you use? Share below!
Top comments (0)