Getting started with Supabase
Advanced

Getting started with Supabase

In this codelab you'll learn what a database is, create a Supabase project, design a data model, build tables, query data with the auto-generated REST API, and protect it with authentication and Row Level Security.

Supabase vs Neon

Both Supabase and Neon give you a cloud PostgreSQL database, but they take different approaches.

  • Supabase is a full backend platform — it bundles your database with built-in authentication, auto-generated REST APIs, realtime subscriptions, and file storage, so you can build an entire app without writing server code.
  • Neon is a focused database service — it gives you a serverless PostgreSQL instance with unique features like database branching and scale-to-zero, but you bring your own auth and API layer.
  • Choose Supabase if you want an all-in-one backend with auth and APIs out of the box.
  • Choose Neon if you want a pure database with advanced features like branching and plan to build your own API.

Looking for a pure database instead? Try our Getting started with Neon codelab.

What you'll use

  • Supabase An open-source Firebase alternative that gives you a PostgreSQL database, auto-generated REST API, authentication, realtime subscriptions, and storage — all from one dashboard. Learn more
  • PostgreSQL The world's most advanced open-source relational database, used by companies of all sizes. Learn more
  • Supabase REST API Supabase auto-generates a REST API from your database schema so you can read and write data from any frontend or backend without writing server code. Learn more
30–45 min

1What is a database?

A database is an organized collection of data that your application can create, read, update, and delete. Think of it as a set of spreadsheets — each table has rows (records) and columns (fields).

Almost every application you use relies on a database behind the scenes:

Real-world examples

  • User accounts — email, password hash, display name, profile photo URL
  • Blog posts — title, content, author, publish date, tags
  • Product catalogs — name, description, price, inventory count, images
  • Analytics events — page visited, timestamp, user ID, device type

When you build a web application, the database is where all the important information lives. The frontend (what users see) talks to a backend (server) that reads and writes to the database.

💡 Where does a database fit?

If you've completed our Deploy web apps with Vercel codelab or the Getting started with Node.js & npm codelab, you've already built the frontend. A database is the missing piece that lets your app store and retrieve real data.

2Why cloud databases?

Traditionally, running a database meant setting up a server, installing database software, managing backups, and handling security patches. Cloud databases remove all of that:

  • No server to manage — the provider handles infrastructure, backups, and updates
  • Accessible from anywhere — connect from your local machine, a server, or an edge function
  • Scales automatically — handles traffic spikes without manual intervention
  • Free tiers — most providers offer generous free plans perfect for learning and side projects

Supabase and Neon are two popular cloud database platforms. Both use PostgreSQL under the hood, but each adds unique features on top.

3What is Supabase?

Supabase is an open-source backend-as-a-service (BaaS) built on top of PostgreSQL. It's often compared to Firebase, but unlike Firebase, Supabase uses a real relational database — giving you the power of SQL with the convenience of a managed platform.

What Supabase gives you

  • PostgreSQL database A full PostgreSQL database with a visual table editor and SQL editor in the dashboard.
  • Auto-generated REST API Supabase automatically creates a RESTful API from your database tables — no backend code needed.
  • Authentication Built-in auth with email/password, magic links, and social providers (Google, GitHub, etc.).
  • Realtime Subscribe to database changes and get live updates in your frontend.
  • Storage Upload and serve files (images, videos, documents) with access policies.
  • Edge functions Run server-side TypeScript functions at the edge for custom logic.

Because Supabase bundles so many features together, it's a great choice for building full-stack apps quickly — especially if you want auth, storage, and a database in one place.

💡 Supabase vs. Neon: If you want a more focused, pure-database experience with features like branching, check out our Getting started with Neon codelab.

4Create a Supabase project

Let's create your first Supabase project:

  1. Go to supabase.com/dashboard
  2. Sign up with GitHub (recommended) or email.
  3. Click "New Project" and choose an organization (or create one).
  4. Enter a project name (e.g. "my-first-project") and choose a region close to you.
  5. Set a strong database password — you'll need it to connect directly with SQL tools.

⚠️ Save your password! Supabase won't show you the database password again. Store it in a password manager or write it down somewhere safe.

5Design your data model

Before creating any tables, take a moment to think about your data model. A data model defines what information your app will store and how the pieces relate to each other.

This is arguably the most important step in building any application. A well-designed data model makes everything easier — queries are simpler, performance is better, and adding new features is straightforward.

⚠️ Think before you build! Changing your data model after your app is in production is much harder than getting it right from the start. Spend time here — it pays off.

Here's an example: imagine you're building a blog. You need posts and comments:

Example: blog data model

Here's how you might define the tables in SQL:

Document contents
-- Create a table for blog posts
CREATE TABLE posts (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  title TEXT NOT NULL,
  content TEXT,
  author_email TEXT NOT NULL,
  published BOOLEAN DEFAULT false,
  created_at TIMESTAMPTZ DEFAULT now()
);

-- Create a table for comments
CREATE TABLE comments (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  post_id UUID REFERENCES posts(id) ON DELETE CASCADE,
  author_name TEXT NOT NULL,
  body TEXT NOT NULL,
  created_at TIMESTAMPTZ DEFAULT now()
);

Tips for designing your data model:

  • Use UUIDs as primary keys for globally unique identifiers
  • Always add a created_at timestamp — you'll need it for sorting and debugging
  • Use foreign keys (REFERENCES) to connect related tables
  • Add sensible default values (DEFAULT false, DEFAULT now()) to reduce the data you need to send with every insert

6Create a table

Now let's create a real table. We'll use a simple todos table to keep things focused:

  1. Open your project in the Supabase dashboard.
  2. Go to the SQL Editor (left sidebar).
  3. Paste the following SQL and click "Run":

Now add some test data:

Document contents
CREATE TABLE todos (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  task TEXT NOT NULL,
  is_complete BOOLEAN DEFAULT false,
  created_at TIMESTAMPTZ DEFAULT now()
);

You can verify your data by going to the Table Editor in the sidebar and clicking on the "todos" table.

Document contents
INSERT INTO todos (task) VALUES ('Learn Supabase');
INSERT INTO todos (task) VALUES ('Build my first app');
INSERT INTO todos (task, is_complete) VALUES ('Create an account', true);

7Query data with the API

One of Supabase's best features is the auto-generated REST API. As soon as you create a table, Supabase creates API endpoints you can call from any frontend or backend.

  1. Go to Project Settings → API to find your project URL and anon key.
  2. Install the Supabase client library in your JavaScript project:

Use the client to read and write data:

Document contents
import { createClient } from '@supabase/supabase-js';

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

// Fetch all todos
const { data, error } = await supabase
  .from('todos')
  .select('*');

console.log(data);

You can also insert, update, and delete records:

Document contents
// Insert a new todo
const { data, error } = await supabase
  .from('todos')
  .insert({ task: 'Deploy to Vercel' })
  .select();

// Update a todo
const { data: updated } = await supabase
  .from('todos')
  .update({ is_complete: true })
  .eq('id', 'some-uuid-here')
  .select();

// Delete a todo
const { error: deleteError } = await supabase
  .from('todos')
  .delete()
  .eq('id', 'some-uuid-here');

Ready to deploy?

Once your app talks to Supabase, you can deploy it instantly with our Deploy web apps with Vercel codelab. Just add your Supabase URL and anon key as environment variables.

8Authentication & Row Level Security

Supabase includes a built-in authentication system. Users can sign up, log in, and manage sessions — and you can write database rules (Row Level Security) that restrict access based on who's logged in.

Auth methods available

  • Email & Password — traditional sign-up with email verification
  • Magic Links — passwordless login via a link sent to the user's email
  • Social Providers — Google, GitHub, Discord, Twitter, and more

Row Level Security (RLS) lets you define rules directly in the database. For example, you can say: "Users can only see and edit their own todos." Here's what that looks like:

Document contents
-- Enable RLS on the todos table
ALTER TABLE todos ENABLE ROW LEVEL SECURITY;

-- Allow users to see only their own todos
CREATE POLICY "Users can view own todos"
  ON todos FOR SELECT
  USING (auth.uid()::text = author_email);

-- Allow users to insert their own todos
CREATE POLICY "Users can insert own todos"
  ON todos FOR INSERT
  WITH CHECK (auth.uid()::text = author_email);

With RLS enabled, even if someone has your anon key, they can only access the data the policies allow.

9Supabase extras

Beyond the database and auth, Supabase offers several additional features:

📦 Storage

Upload and serve files (images, videos, PDFs) with fine-grained access policies. Great for profile photos, attachments, and media. File storage with Supabase Storage

Realtime

Subscribe to database changes and receive live updates in your app. Perfect for chat apps, dashboards, and collaborative tools.

🔗 Edge functions

Write custom server-side TypeScript functions that run at the edge. Use them for webhooks, payment processing, or any logic you don't want in the client.

🤖 AI & vectors

Store and query vector embeddings for AI/ML workloads. Build semantic search, recommendation systems, and RAG applications.

🆓 Free plan limits

  • 500 MB database space
  • 1 GB file storage
  • 2 GB bandwidth per month
  • 50,000 monthly active users (auth)
  • 500,000 Edge Function invocations per month

📖 Lesson: See how databases fit into web application architecture in our Elements of a web application lesson.

🎉

You're all set!

You now have a Supabase project with a database, tables, API access, and an understanding of authentication and Row Level Security. You're ready to build real applications with persistent data!

Back to codelabs

How was this codelab?

Let us know what you thought — suggestions, issues, or anything else.

Getting started with Supabase