DEV Community

Alex Spinov
Alex Spinov

Posted on

Supabase Has a Free API — The Open-Source Firebase Alternative with Postgres

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
Enter fullscreen mode Exit fullscreen mode
import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
  'https://YOUR_PROJECT.supabase.co',
  'YOUR_ANON_KEY'
);
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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`);
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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)