📚Academy
likeone
online

Supabase 101

Supabase gives you a Postgres database, auth, edge functions, and real-time subscriptions — all in one platform. It replaces five separate services and is the foundation of your entire AI stack.

Why Supabase Is the Foundation

Most backend setups require stitching together a database (RDS), authentication (Auth0), serverless functions (Lambda), real-time features (Pusher), and file storage (S3). Supabase bundles all of these into one platform built on Postgres — the most battle-tested database in existence.

For AI applications specifically, Supabase adds pgvector — a Postgres extension that stores AI embeddings (numerical representations of text meaning) and enables semantic search. This means your AI agent can find memories by meaning, not just keywords.

🗄️
Postgres
Full SQL database with JSONB, indexes, and 30+ years of reliability
🔒
Auth + RLS
User management + row-level security — the database enforces who sees what
🧠
pgvector
Store AI embeddings and search by meaning — the foundation of AI memory

Two Keys, Two Levels of Access

When you create a Supabase project, you get two API keys. Understanding the difference between them is the most important security concept in this entire course.

Anon Key (Public)

Safe for frontend. Can be seen in browser source code. Designed to be public. RLS policies control what it can access — without policies, it can access nothing.

eyJhbGciOi... // public, safe
Service Role Key (Secret)

Server-side ONLY. Bypasses ALL RLS. Full access to every table, every row. If this key leaks, your entire database is compromised.

eyJhbGciOi... // SECRET, never in browser

Step-by-Step: Create Your First Project

Follow these steps to go from zero to a working Supabase project with a table, RLS, and your first data.

1. Go to supabase.com and create a new project. Pick a region close to your users.
2. Save your Project URL, Anon Key, and Service Role Key from Settings → API.
3. Open the SQL Editor in the dashboard — this is where you run all database commands.
4. Create your first table (SQL below).
5. Enable RLS and create an access policy.
6. Insert your first record to verify everything works.

Create the brain_context Table

This table stores your AI agent's memory as key-value pairs. It is the single most important table in any AI application — the agent's persistent brain.

SQL — Create brain_context with pgvector support
-- Enable the vector extension for AI embeddings
CREATE EXTENSION IF NOT EXISTS vector;

CREATE TABLE brain_context (
  id          uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  key         text UNIQUE NOT NULL,     -- dot notation: 'identity.name'
  value       jsonb,                    -- flexible structured data
  category    text DEFAULT 'general',  -- session, directive, system
  description text,                     -- human-readable note
  embedding   vector(384),             -- BGE-small AI embeddings
  priority    int DEFAULT 5,
  updated_at  timestamptz DEFAULT now()
);

-- Fast lookups by key
CREATE INDEX idx_brain_key ON brain_context(key);
CREATE INDEX idx_brain_category ON brain_context(category);

-- Semantic search index (cosine similarity)
CREATE INDEX idx_brain_embedding
  ON brain_context
  USING ivfflat (embedding vector_cosine_ops)
  WITH (lists = 100);
Column breakdown: key uses dot notation (identity.name, session.active_work) for organization. value is JSONB — a binary JSON format that supports indexing and querying inside the structure. embedding stores 384 numbers representing the semantic meaning of the key's content (for AI search).

Enable Row Level Security

RLS is the bouncer for your database. Without it, anyone with your anon key can read all data. With it, the database itself enforces who can see what — even if your application code has bugs.

SQL — Enable RLS and create a service role policy
-- Enable RLS — default-deny: nobody can access without a policy
ALTER TABLE brain_context ENABLE ROW LEVEL SECURITY;

-- Allow the service role (backend only) full access
CREATE POLICY "service_role_all" ON brain_context
  FOR ALL TO service_role
  USING (true);

-- The anon key (frontend) gets NOTHING by default
-- Add more policies later if users need direct access
Critical: Enabling RLS with no policies creates a default-deny state — nobody can access the table. This is the safe default. You explicitly create policies to grant access. Start locked down, open up only what is needed.

Essential SQL Queries

Run these in the Supabase SQL Editor. They cover the four operations you will use constantly: read, write, update, and filter.

SQL — Essential brain_context queries
-- READ: Fetch all rows (most recent first)
SELECT key, value, updated_at
FROM brain_context
ORDER BY updated_at DESC;

-- WRITE: Insert a new key-value pair
INSERT INTO brain_context (key, value, category)
VALUES ('identity.name', '"AI Stack Builder Student"', 'identity');

-- UPSERT: Write or update (no need to check if key exists)
INSERT INTO brain_context (key, value, category)
VALUES ('session.active_work', '{"task":"building"}', 'session')
ON CONFLICT (key) DO UPDATE SET
  value = EXCLUDED.value,
  updated_at = now();

-- FILTER: Find all session keys
SELECT key, value FROM brain_context
WHERE key LIKE 'session.%';

Supabase Client: JavaScript SDK

In production, you interact with Supabase through the JavaScript SDK — not raw SQL. The SDK provides type-safe methods for every operation.

JavaScript — Supabase client setup + queries
import { createClient } from '@supabase/supabase-js'

// Initialize (these are safe for the frontend)
const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
)

// READ — Fetch the 10 most recently updated brain keys
const { data, error } = await supabase
  .from('brain_context')
  .select('key, value, updated_at')
  .order('updated_at', { ascending: false })
  .limit(10)

// UPSERT — Write or update a key-value pair
const { error: writeErr } = await supabase
  .from('brain_context')
  .upsert({
    key: 'session.active_work',
    value: { task: 'Building the AI stack', status: 'in_progress' }
  }, { onConflict: 'key' })

// FILTER — Find all keys matching a pattern
const { data: sessions } = await supabase
  .from('brain_context')
  .select('*')
  .like('key', 'session.%')

The Five Superpowers of Supabase

Each of these replaces a separate service you would otherwise need to set up, configure, and maintain independently.

Feature What It Does Replaces
Postgres Database Full SQL database with JSONB, views, triggers, and 30+ years of reliability AWS RDS, PlanetScale, MongoDB
Auth + RLS User signup/login, JWT tokens, row-level access control Auth0, Firebase Auth, Clerk
Edge Functions Serverless TypeScript functions deployed globally (Deno runtime) AWS Lambda, Cloudflare Workers
Realtime Live subscriptions — your UI updates instantly when data changes Pusher, Socket.io, Firebase Realtime
pgvector Store AI embeddings, search by semantic meaning Pinecone, Weaviate, Chroma
Cost: Supabase Pro is $25/month and includes all five features. The free tier gives you 2 projects with generous limits for learning and prototyping.
Academy
Built with soul — likeone.ai