DEV Community

Cover image for Supabase: Open Source Backend-as-a-Service Made Simple
Austin
Austin

Posted on

Supabase: Open Source Backend-as-a-Service Made Simple

πŸ‘‹ Let's Connect! Follow me on GitHub for new projects.


Introduction

In the evolving landscape of web development, integrating robust backend services efficiently is paramount. Supabase has emerged as a compelling solution, offering developers a comprehensive suite of tools to build scalable applications with ease. This article provides an overview of Supabase, its core features, and practical applications, along with hands-on code examples to get started with authentication, database setup, and security settings.


Understanding Supabase

Supabase is an open-source backend-as-a-service (BaaS) solution that simplifies backend development by offering a managed PostgreSQL database, authentication, real-time capabilities, storage, and serverless functions.

Key Features of Supabase*

  • Managed PostgreSQL Database – Full control over a scalable database with SQL support.
  • Authentication – Built-in auth with email/password, OAuth, and magic links.
  • Real-Time Database Updates – Listen for changes in your database live.
  • File Storage – Store and serve media assets securely.
  • Edge Functions – Deploy serverless functions for custom backend logic.

Getting Started with Supabase

Before writing any code, you'll need to set up a Supabase project.

1. Creating a Supabase Project

  1. Sign up at Supabase and create a new project.
  2. Copy your project’s API URL and anon/public API key from the dashboard.
  3. Install the Supabase JavaScript SDK in your project:
   npm install @supabase/supabase-js
Enter fullscreen mode Exit fullscreen mode
  1. Initialize Supabase in your project:
   import { createClient } from '@supabase/supabase-js';

   const supabaseUrl = 'https://your-project.supabase.co'; // Replace with your project URL
   const supabaseKey = 'your-anon-public-key'; // Replace with your anon key
   const supabase = createClient(supabaseUrl, supabaseKey);
Enter fullscreen mode Exit fullscreen mode

Setting Up a Database

Let’s create a simple todos table to store user tasks.

2. Creating a Table in Supabase

  1. Go to Database > Tables in the Supabase dashboard and create a table:

    • Table Name: todos
    • Columns:
      • id (UUID, primary key, default: gen_random_uuid())
      • user_id (UUID, foreign key linked to auth.users)
      • title (TEXT)
      • completed (BOOLEAN, default: false)
      • created_at (TIMESTAMP, default: now())
  2. Run this SQL to create the table (optional if using SQL Editor in Supabase):

   create table todos (
       id uuid primary key default gen_random_uuid(),
       user_id uuid references auth.users on delete cascade,
       title text not null,
       completed boolean default false,
       created_at timestamp default now()
   );
Enter fullscreen mode Exit fullscreen mode
  1. Enable Row-Level Security (RLS) on the table and add policies (see next section).

Implementing Authentication

Supabase provides easy-to-use authentication methods, including email/password, Google, GitHub, and magic links.

3. User Sign-Up and Login

Let’s add authentication to allow users to register and sign in.

Sign Up a New User

async function signUp(email, password) {
  const { user, error } = await supabase.auth.signUp({ email, password });

  if (error) {
    console.error('Error signing up:', error.message);
  } else {
    console.log('User signed up:', user);
  }
}
Enter fullscreen mode Exit fullscreen mode

Sign In a User

async function signIn(email, password) {
  const { user, error } = await supabase.auth.signInWithPassword({ email, password });

  if (error) {
    console.error('Error signing in:', error.message);
  } else {
    console.log('User signed in:', user);
  }
}
Enter fullscreen mode Exit fullscreen mode

Sign Out

async function signOut() {
  const { error } = await supabase.auth.signOut();
  if (error) console.error('Error signing out:', error.message);
  else console.log('User signed out');
}
Enter fullscreen mode Exit fullscreen mode

Securing the Database

By default, Supabase uses Row-Level Security (RLS), meaning users cannot access data unless explicitly permitted.

4. Adding RLS Policies

  1. Enable RLS for todos in the dashboard.
  2. Run the following policies:

Allow Users to See Only Their Own Todos

create policy "Users can view their own todos"
on todos
for select
using (auth.uid() = user_id);
Enter fullscreen mode Exit fullscreen mode

Allow Users to Insert Their Own Todos

create policy "Users can insert their own todos"
on todos
for insert
with check (auth.uid() = user_id);
Enter fullscreen mode Exit fullscreen mode

Allow Users to Update Only Their Own Todos

create policy "Users can update their own todos"
on todos
for update
using (auth.uid() = user_id);
Enter fullscreen mode Exit fullscreen mode

Fetching and Managing Todos

Now that the backend is set up, let’s interact with the todos table.

5. Fetch Todos for the Logged-in User**

async function getTodos() {
  const { data, error } = await supabase
    .from('todos')
    .select('*')
    .eq('user_id', (await supabase.auth.getUser()).data.user.id);

  if (error) console.error('Error fetching todos:', error.message);
  return data;
}
Enter fullscreen mode Exit fullscreen mode

6. Adding a New Todo

async function addTodo(title) {
  const user = (await supabase.auth.getUser()).data.user;

  const { data, error } = await supabase
    .from('todos')
    .insert([{ title, user_id: user.id }]);

  if (error) console.error('Error adding todo:', error.message);
  return data;
}
Enter fullscreen mode Exit fullscreen mode

7. Updating a Todo**

async function toggleTodo(id, completed) {
  const { data, error } = await supabase
    .from('todos')
    .update({ completed })
    .eq('id', id);

  if (error) console.error('Error updating todo:', error.message);
  return data;
}
Enter fullscreen mode Exit fullscreen mode

8. Deleting a Todo*

async function deleteTodo(id) {
  const { data, error } = await supabase
    .from('todos')
    .delete()
    .eq('id', id);

  if (error) console.error('Error deleting todo:', error.message);
  return data;
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

Supabase provides an open-source alternative to backend services like Firebase, with PostgreSQL, authentication, real-time updates, and serverless functions. In this guide, we:

  • Set up a Supabase project
  • Created a database and implemented authentication
  • Secured the database with basic Row-Level Security (RLS)
  • Implemented CRUD operations for a simple todo list

With this foundation, you can build full-stack applications with minimal backend setup. Whether you're developing a CMS, an e-commerce site, or a real-time chat app, Supabase can be a great option. Be sure to read further about security and best practices in Supabase.


Meta Description:

Learn how to build a full-stack backend with Supabase, PostgreSQL, authentication, and secure database access. Step-by-step guide with code examples.


TLDR - Highlights for Skimmers:

  • Supabase Overview: An open-source backend-as-a-service platform.
  • Database Setup: PostgreSQL-powered database with real-time capabilities.
  • Authentication: Built-in user authentication with email/password.
  • Row-Level Security (RLS): Ensures secure access to user data.
  • CRUD Operations: Manage todos with insert, update, delete, and fetch operations.

Have you tried Supabase in your projects? Share your thoughts and experiences below!

Top comments (0)