Supabase

An open-source Firebase alternative built on Postgres.

What is it?

Supabase is a backend-as-a-service platform that bundles a real PostgreSQL database with auto-generated APIs, authentication, file storage, and real-time subscriptions - the same pitch as Firebase, but built on an open-source, standard SQL database instead of a proprietary document store. You get a full backend without writing one, while keeping your data in a database you could self-host or export at any time.


When to use it

Supabase is a strong pick when you want Firebase-style speed - instant APIs, built-in auth, live updates - but also want real SQL: relational data, joins, and the ability to run standard Postgres tooling against your database. It's younger than Firebase, so while its community is now large, there are still fewer beginner tutorials for real-time apps specifically. For a first project with structured data and no real-time requirement, plain PostgreSQL or MySQL is simpler to reason about; for real-time needs with the largest ecosystem, Firebase is more established.


Core concepts

  • It's just Postgres - your data lives in a standard PostgreSQL database; anything you know about SQL applies directly.
  • Auto-generated APIs - create a table and Supabase instantly exposes a REST and GraphQL-like API for it, no backend code required.
  • Row-level security (RLS) - instead of writing server-side authorization checks, you write Postgres policies that decide which rows a given user is allowed to read or write.
  • Real-time subscriptions - the client can subscribe to changes on a table and receive live updates, similar to Firestore's real-time listeners.
  • Built-in auth and storage - email/password and social login, plus file storage, ship as part of the platform alongside the database.

A taste of the code

import { createClient } from "@supabase/supabase-js";
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);

const { data, error } = await supabase
  .from("posts")
  .select("*")
  .eq("published", true);

No backend route to write - the client library talks to the auto-generated API directly, with row-level security policies deciding what data actually comes back.


Your first steps

  1. Create a free project at supabase.com - this provisions a real Postgres database for you.
  2. Create a table in the dashboard's table editor and note how an API for it appears immediately under the API docs tab.
  3. In a React or plain JS project, install the client with npm install @supabase/supabase-js and run your first select() query.
  4. Enable row-level security on your table and write a policy so users can only see their own rows - this is the piece most worth understanding well before shipping anything real.
  5. Subscribe to a table's changes with supabase.channel() to see real-time updates working end to end.

Common beginner mistakes

  • Tables without Row Level Security. Any table the browser can reach needs RLS enabled and policies that say who can read and write which rows. Check every table, especially ones created with SQL.
  • Using the service role key in frontend code. It bypasses RLS entirely. Only the public (anon) key belongs in the browser; the service key stays on servers.
  • Not cleaning up realtime channels when a component or page goes away.
  • Doing everything through the client library. For complex logic, a Postgres function or view is often simpler and faster.
  • Forgetting free projects can pause after a period of inactivity - fine for learning, not for a live site people depend on.

Getting it online

Supabase hosts the database, auth and storage for you; your frontend can be deployed to any static host. For local development, the Supabase CLI runs the whole stack on your machine with Docker, and lets you keep schema changes in migration files.


← Back to Stack Picker All primers Compare databases