Skip to content

Complete Supabase + React guide with TypeScript & Vite - Auth, Database, Realtime, Storage, RLS & more!

License

Notifications You must be signed in to change notification settings

ArmenSl/awesome-supabase-react

Repository files navigation

🚀 Supabase React Showcase

The Complete Guide to Building with Supabase

FeaturesQuick StartDocsContributing

TypeScript React Supabase Vite

GitHub stars GitHub forks


🎯 What is This?

A complete, production-ready reference for building applications with Supabase. Not just a todo app—this showcases every major Supabase feature with real-world examples you can copy directly into your projects.

Perfect for:

  • 🎓 Learning Supabase from scratch
  • 📚 Reference when building your own apps
  • 🚀 Starter template for new projects
  • 👥 Teaching others how to use Supabase

Live Demo: [Coming Soon] | Video Tutorial: [Coming Soon]


📋 Table of Contents


✨ Features

🔐 Authentication

  • ✅ Email/password signup & login
  • ✅ Magic links (passwordless authentication)
  • ✅ OAuth (GitHub, Google)
  • ✅ Session management & persistence
  • ✅ Protected routes
  • ✅ Sign out

💾 Database Operations

  • ✅ Full CRUD (Create, Read, Update, Delete)
  • ✅ TypeScript types generated from schema
  • ✅ Filtering (eq, gte, lte, ilike, or)
  • ✅ Ordering & sorting
  • ✅ Pagination (range)
  • ✅ Joins & nested selects (foreign key relationships)
  • ✅ Counting & aggregations
  • ✅ Upsert operations

🔒 Row Level Security (RLS)

  • ✅ User-specific data policies
  • ✅ Public vs private data
  • ✅ INSERT/UPDATE/DELETE restrictions
  • ✅ Live demo of policy enforcement

⚡ Realtime

  • ✅ Subscribe to INSERT/UPDATE/DELETE events
  • ✅ Live UI updates across clients
  • ✅ Presence (who's online)

📁 Storage

  • ✅ File uploads (images, documents)
  • ✅ Public vs protected buckets
  • ✅ File validation (type, size)
  • ✅ Public URL generation
  • ✅ Signed URLs for private files

🌐 Edge Functions

  • ✅ Service layer ready for edge function calls
  • ✅ Examples for custom business logic
  • ✅ Payment processing patterns
  • ✅ Webhook handlers

🔧 RPC (Postgres Functions)

  • ✅ Call custom Postgres functions
  • ✅ Complex queries & aggregations
  • ✅ Transaction-like behavior
  • ✅ Return tables or JSON

📁 Project Structure

supabase-app/
├── src/
│   ├── lib/
│   │   ├── supabaseClient.ts      # Supabase client initialization
│   │   └── database.types.ts      # TypeScript types from schema
│   ├── hooks/
│   │   ├── useAuth.ts             # Authentication hooks & functions
│   │   └── useRealtime.ts         # Realtime subscription hooks
│   ├── services/
│   │   ├── libraryService.ts      # CRUD operations for library/books
│   │   ├── storageService.ts      # File upload/download functions
│   │   ├── rpcService.ts          # RPC (Postgres function) calls
│   │   └── edgeFunctionsService.ts # Edge function wrappers
│   ├── components/
│   │   ├── AuthForm.tsx           # Email/OAuth/Magic link auth UI
│   │   ├── LibraryManager.tsx     # Full CRUD demo with UI
│   │   ├── RealtimeMessages.tsx   # Live message feed
│   │   ├── FileUpload.tsx         # File upload with preview
│   │   └── RLSDemo.tsx            # RLS policy demonstration
│   ├── App.tsx                    # Main app with tab navigation
│   └── main.tsx                   # App entry point
├── .env.local                     # Environment variables (create this)
└── README.md

🎯 Design Principles

  • Separation of Concerns: Hooks for state, services for data, components for UI
  • TypeScript First: Full type safety from database schema
  • Real-world Examples: Practical patterns you can copy directly
  • Commented Code: Every feature explained inline
  • Error Handling: Proper error states and loading indicators

⚡ Quick Start

Get up and running in 10 minutes! See QUICKSTART.md for detailed instructions.

# 1. Clone the repository
git clone https://github.com/yourusername/supabase-react-showcase.git
cd supabase-react-showcase

# 2. Install dependencies
npm install

# 3. Set up environment variables
cp .env.local.template .env.local
# Edit .env.local with your Supabase credentials

# 4. Run the app
npm run dev

Then set up your Supabase database using supabase-setup.sql - full instructions in QUICKSTART.md!


📖 Detailed Setup Guide

1. Prerequisites

  • Node.js 18+ and npm/yarn
  • A Supabase account (supabase.com)

2. Clone & Install

cd supabase-app
npm install

3. Environment Variables

Create a .env.local file in the root:

VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key-here

Get these from your Supabase dashboard: Settings > API


🗄️ Database Setup

Run these SQL commands in your Supabase SQL Editor (Database > SQL Editor):

1. Core Tables

-- Library table
CREATE TABLE library (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  address VARCHAR(100) NOT NULL,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Book table
CREATE TABLE book (
  id SERIAL PRIMARY KEY,
  title VARCHAR(100) NOT NULL,
  pages INTEGER NOT NULL,
  release DATE NOT NULL,
  locatedIn_id INTEGER NOT NULL REFERENCES library(id) ON DELETE CASCADE,
  cover_url TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Author table
CREATE TABLE author (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(100) NOT NULL UNIQUE,
  user_id UUID REFERENCES auth.users(id),
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Author-Book junction table (many-to-many)
CREATE TABLE author_book (
  publishes INTEGER NOT NULL REFERENCES book(id) ON DELETE CASCADE,
  "writtenBy" INTEGER NOT NULL REFERENCES author(id) ON DELETE CASCADE,
  PRIMARY KEY (publishes, "writtenBy")
);

2. User Profiles (for RLS demo)

CREATE TABLE user_profiles (
  id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
  username TEXT UNIQUE NOT NULL,
  bio TEXT,
  avatar_url TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

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

-- RLS Policies
CREATE POLICY "Profiles are viewable by everyone"
  ON user_profiles FOR SELECT
  USING (true);

CREATE POLICY "Users can insert their own profile"
  ON user_profiles FOR INSERT
  WITH CHECK (auth.uid() = id);

CREATE POLICY "Users can update their own profile"
  ON user_profiles FOR UPDATE
  USING (auth.uid() = id);

CREATE POLICY "Users can delete their own profile"
  ON user_profiles FOR DELETE
  USING (auth.uid() = id);

3. Messages Table (for Realtime demo)

CREATE TABLE messages (
  id SERIAL PRIMARY KEY,
  user_id TEXT NOT NULL,
  content TEXT NOT NULL,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Enable Realtime
ALTER PUBLICATION supabase_realtime ADD TABLE messages;

-- Optional: Enable RLS for user-specific messages
ALTER TABLE messages ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Users can read their own messages"
  ON messages FOR SELECT
  USING (auth.uid()::text = user_id);

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

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

4. Sample RPC Functions

-- Count books in a library
CREATE OR REPLACE FUNCTION get_books_count_by_library(library_id INTEGER)
RETURNS INTEGER
LANGUAGE plpgsql
AS $$
DECLARE
  book_count INTEGER;
BEGIN
  SELECT COUNT(*)
  INTO book_count
  FROM book
  WHERE "locatedIn_id" = library_id;
  
  RETURN book_count;
END;
$$;

-- Search books by title
CREATE OR REPLACE FUNCTION search_books(search_term TEXT)
RETURNS SETOF book
LANGUAGE plpgsql
AS $$
BEGIN
  RETURN QUERY
  SELECT *
  FROM book
  WHERE title ILIKE '%' || search_term || '%'
  ORDER BY title;
END;
$$;

-- Get library statistics
CREATE OR REPLACE FUNCTION get_library_stats(library_id INTEGER)
RETURNS JSON
LANGUAGE plpgsql
AS $$
DECLARE
  result JSON;
BEGIN
  SELECT json_build_object(
    'total_books', COUNT(*),
    'total_pages', COALESCE(SUM(pages), 0),
    'avg_pages', COALESCE(AVG(pages), 0),
    'oldest_book', MIN(release),
    'newest_book', MAX(release)
  )
  INTO result
  FROM book
  WHERE "locatedIn_id" = library_id;
  
  RETURN result;
END;
$$;

⚙️ Supabase Configuration

1. Enable Realtime

Go to Database > Replication:

  • Enable replication for messages table
  • This allows real-time subscriptions

2. Configure Authentication

Go to Authentication > Providers:

  • Email: Enable email provider
  • Magic Link: Enable passwordless sign-in (optional)
  • GitHub OAuth: Add GitHub OAuth app credentials (optional)
  • Google OAuth: Add Google OAuth credentials (optional)

3. Create Storage Buckets

Go to Storage > Create bucket:

  • Create avatars bucket (public)
  • Create book-covers bucket (public)

For each bucket, toggle Public bucket to ON.

4. Generate Types (Optional)

# Install Supabase CLI
npm install -g supabase

# Login
supabase login

# Generate types
npx supabase gen types typescript --project-id your-project-id > src/lib/database.types.ts

🏃 Running the App

npm run dev

Open http://localhost:5173


📚 Feature Guides

Authentication Flow

  1. Sign Up: Users enter email/password → confirmation email sent
  2. Sign In: Email/password OR magic link OR OAuth
  3. Session: Auto-persisted in localStorage
  4. Protected Content: App shows features only when authenticated

CRUD Operations

  • Create: supabase.from('table').insert(data)
  • Read: supabase.from('table').select('*')
  • Update: supabase.from('table').update(data).eq('id', id)
  • Delete: supabase.from('table').delete().eq('id', id)

Realtime Setup

const channel = supabase
  .channel('my-channel')
  .on('postgres_changes', { event: '*', schema: 'public', table: 'messages' }, (payload) => {
    console.log('Change received!', payload)
  })
  .subscribe()

File Upload

const { data, error } = await supabase.storage
  .from('bucket-name')
  .upload('path/to/file.jpg', fileObject)

RPC Call

const { data, error } = await supabase.rpc('my_function', {
  param1: value1,
  param2: value2,
})

🎓 Learning Resources


📚 Documentation


🤝 Contributing

Contributions are welcome! Whether it's:

  • 🐛 Bug fixes
  • ✨ New features or examples
  • 📝 Documentation improvements
  • 💡 Suggestions

Please read CONTRIBUTING.md for guidelines.

Contributors

Thanks to all the amazing people who have contributed to this project!


⭐ Show Your Support

If this project helped you, please consider:

  • Starring the repository
  • 🐦 Sharing on Twitter
  • 📝 Writing a blog post about it
  • 💬 Telling others who might find it useful

📝 License

This project is MIT licensed. Use it freely in your projects!


🙏 Acknowledgments

  • Supabase - For building an amazing platform
  • Vite - For the blazing fast dev experience
  • Community - For feedback and contributions

Built with ❤️ for the Supabase community

Share on Twitter

About

Complete Supabase + React guide with TypeScript & Vite - Auth, Database, Realtime, Storage, RLS & more!

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

Packages

No packages published