Claude Skills Guide

Claude Code with Supabase Auth and Database Guide

Supabase is an open-source Firebase alternative that provides authentication, database, real-time subscriptions, and edge functions. When combined with Claude Code, you can rapidly build secure, data-driven applications without the complexity of traditional backend setups. This guide covers the full Supabase integration — auth setup, database schema design, CRUD operations, and real-time subscriptions. For a deep dive into Row Level Security policies and fine-grained access control, see the Supabase Auth RLS Guide.

Why Supabase with Claude Code?

Supabase offers several compelling advantages for developers using Claude Code:

Claude Code can help you set up Supabase projects, write database migrations, implement auth flows, and build type-safe queries—all through natural conversation.

Setting Up Your Supabase Project

Before integrating with Claude Code, create a Supabase project and obtain your credentials:

  1. Visit supabase.com and create a new project
  2. Note your Project URL and anon public key from Settings > API
  3. Install the Supabase JavaScript client in your project:
npm install @supabase/supabase-js

Configuring the Supabase Client

Create a centralized Supabase client configuration:

// lib/supabase.ts
import { createClient } from '@supabase/supabase-js'

const supabaseUrl = process.env.SUPABASE_URL!
const supabaseAnonKey = process.env.SUPABASE_ANON_KEY!

export const supabase = createClient(supabaseUrl, supabaseAnonKey)

Implementing Authentication

Supabase handles authentication out of the box with email/password, OAuth providers, and magic links. Here’s how to implement common auth patterns.

Sign Up and Sign In

// auth/signup.ts
import { supabase } from '../lib/supabase'

export async function signUp(email: string, password: string) {
  const { data, error } = await supabase.auth.signUp({
    email,
    password,
  })
  
  if (error) throw new Error(error.message)
  return data
}

export async function signIn(email: string, password: string) {
  const { data, error } = await supabase.auth.signInWithPassword({
    email,
    password,
  })
  
  if (error) throw new Error(error.message)
  return data
}

Protecting Routes with Auth Checks

Create middleware to protect routes:

// middleware/auth.ts
import { supabase } from '../lib/supabase'
import type { SupabaseClient, User } from '@supabase/supabase-js'

export async function requireAuth(supabaseClient: SupabaseClient) {
  const { data: { session }, error } = await supabaseClient.auth.getSession()
  
  if (error || !session) {
    throw new Error('Authentication required')
  }
  
  return session.user
}

Database Schema Design

Design your database schema with RLS in mind from the start. Here’s a practical example of a todo application:

-- Create todos table
CREATE TABLE todos (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE NOT NULL,
  title TEXT NOT NULL,
  completed BOOLEAN DEFAULT false,
  created_at TIMESTAMPTZ DEFAULT now(),
  updated_at TIMESTAMPTZ DEFAULT now()
);

-- Enable RLS
ALTER TABLE todos ENABLE ROW LEVEL SECURITY;

-- Policy: Users can only see their own todos
CREATE POLICY "Users can view own todos" ON todos
  FOR SELECT
  USING (auth.uid() = user_id);

-- Policy: Users can insert their own todos
CREATE POLICY "Users can insert own todos" ON todos
  FOR INSERT
  WITH CHECK (auth.uid() = user_id);

-- Policy: Users can update their own todos
CREATE POLICY "Users can update own todos" ON todos
  FOR UPDATE
  USING (auth.uid() = user_id);

-- Policy: Users can delete their own todos
CREATE POLICY "Users can delete own todos" ON todos
  FOR DELETE
  USING (auth.uid() = user_id);

CRUD Operations with Type Safety

Use Supabase’s type generator to get full TypeScript type safety:

// lib/types.ts
export type Todo = {
  id: string
  user_id: string
  title: string
  completed: boolean
  created_at: string
  updated_at: string
}

Creating Records

// todos/create.ts
import { supabase } from '../lib/supabase'
import type { Todo } from '../lib/types'

export async function createTodo(title: string, userId: string): Promise<Todo> {
  const { data, error } = await supabase
    .from('todos')
    .insert({
      title,
      user_id: userId,
    })
    .select()
    .single()
  
  if (error) throw new Error(error.message)
  return data
}

Reading Records

// todos/list.ts
import { supabase } from '../lib/supabase'
import type { Todo } from '../lib/types'

export async function listTodos(userId: string): Promise<Todo[]> {
  const { data, error } = await supabase
    .from('todos')
    .select('*')
    .eq('user_id', userId)
    .order('created_at', { ascending: false })
  
  if (error) throw new Error(error.message)
  return data || []
}

Updating Records

// todos/toggle.ts
import { supabase } from '../lib/supabase'

export async function toggleTodo(todoId: string, userId: string, completed: boolean) {
  const { error } = await supabase
    .from('todos')
    .update({ 
      completed,
      updated_at: new Date().toISOString()
    })
    .eq('id', todoId)
    .eq('user_id', userId)
  
  if (error) throw new Error(error.message)
}

Using Claude Code with Supabase

Claude Code can accelerate your Supabase development workflow in several ways:

Prompt Example for Database Design

“Help me design a Supabase database schema for a task management app with users, projects, tasks, and comments. Include RLS policies for multi-tenant access.”

Claude Code will generate appropriate SQL, suggest indexes, and create secure RLS policies.

Prompt Example for Auth Integration

“Write the TypeScript code to implement OAuth sign-in with GitHub using Supabase Auth, including error handling and session persistence.”

Prompt Example for Real-time Features

“Create a React hook that subscribes to Supabase real-time changes for a chat messages table and handles connection status.”

Best Practices

  1. Always enable RLS - Never skip Row Level Security, even for prototyping
  2. Use service roles sparingly - Only use the service role key server-side for admin operations
  3. Validate on both layers - Add database constraints AND application validation
  4. Monitor auth events - Use Supabase’s auth hooks for logging and analytics
  5. Keep tokens secure - Never expose access tokens in client-side code

Conclusion

Supabase provides a powerful backend-as-a-service platform that pairs excellently with Claude Code’s development capabilities. By leveraging Supabase’s auth system and PostgreSQL database with RLS, you can build secure applications faster while maintaining data integrity. Claude Code can help you generate schemas, write queries, and implement auth patterns—all through natural conversation, making it an invaluable partner for Supabase development.

Start with a small proof-of-concept, validate your auth flow, then expand to full CRUD operations. The combination of Supabase’s developer experience and Claude Code’s assistance makes building data-driven applications more accessible than ever.

Built by theluckystrike — More at zovo.one