About

evolving · Apr 22, 2026 · 2 min read

Supabase

Supabase is an open-source backend-as-a-service (BaaS) built on top of PostgreSQL. The idea is that instead of building your own backend infrastructure — database, authentication, file storage, real-time subscriptions — Supabase gives you all of that out of the box, wired together and ready to use via a simple client library.

It's often described as the open-source alternative to Firebase, but unlike Firebase (which uses a NoSQL document store), Supabase is backed by a real relational database. You get the full power of PostgreSQL: SQL queries, joins, stored functions, indexes, and RLS.


What Supabase provides


Two access levels

Every Supabase project comes with two keys:

Key Name Scope
anon Public key Subject to RLS policies
service_role Secret key Bypasses RLS entirely

The anon key is safe to expose in frontend code (it's prefixed NEXT_PUBLIC_ in Next.js projects). The service role key must stay server-side only. If RLS is not configured on a table, anyone with the anon key can query that table directly — which is a common misconfiguration trap.


RPC: calling database functions

Supabase exposes a way to call PostgreSQL stored functions remotely via .rpc(). This is called RPC (Remote Procedure Call): you write logic as a function in the database, then invoke it like an API endpoint from your app.

const { data, error } = await supabase.rpc('create_booking_atomic', {
  p_venue_id: venueId,
  p_date: date,
  // ...other params
})

RPC is useful when you need to run logic that must be atomic at the database level — for example, checking for a conflict and inserting a row in a single transaction. Doing this in application code with two separate queries creates a race condition; doing it in a stored function and calling it via RPC keeps everything inside one database transaction.


Typical client setup (Next.js)

In a Next.js app, Supabase recommends using @supabase/ssr which handles cookie-based session management:

// lib/supabase/server.ts — anon client for guest/public operations
import { createServerClient } from '@supabase/ssr'

export function createClient() {
  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    { cookies: { ... } }
  )
}

A second client using the service role key bypasses RLS and is used for admin operations. That key must never appear in NEXT_PUBLIC_ variables.


Sources

  1. Supabase Docs
  2. Supabase RPC
  3. Supabase Auth