DEV Community

Alex Spinov
Alex Spinov

Posted on

Supabase Auth Has Free Authentication — Here's How to Add Login to Any App in 10 Minutes

Rolling your own auth is dangerous. Buying Clerk is expensive. Supabase Auth is free, secure, and works with any framework.

What is Supabase Auth?

Supabase Auth is a free, open-source authentication system built on GoTrue. It supports email/password, magic links, phone auth, and 20+ social providers — all with Row Level Security built in.

Free Tier

  • 50,000 monthly active users
  • Unlimited API requests
  • Social OAuth (Google, GitHub, Discord, etc.)
  • Email/password
  • Magic links
  • Phone auth (OTP)

Quick Start

bun add @supabase/supabase-js
Enter fullscreen mode Exit fullscreen mode
import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_ANON_KEY!
);
Enter fullscreen mode Exit fullscreen mode

Email/Password Auth

// Sign up
const { data, error } = await supabase.auth.signUp({
  email: 'alice@example.com',
  password: 'securepassword123',
});

// Sign in
const { data, error } = await supabase.auth.signInWithPassword({
  email: 'alice@example.com',
  password: 'securepassword123',
});

// Sign out
await supabase.auth.signOut();

// Get current user
const { data: { user } } = await supabase.auth.getUser();
Enter fullscreen mode Exit fullscreen mode

Social Login (One Line)

// Google
await supabase.auth.signInWithOAuth({ provider: 'google' });

// GitHub
await supabase.auth.signInWithOAuth({ provider: 'github' });

// Discord
await supabase.auth.signInWithOAuth({ provider: 'discord' });

// Apple
await supabase.auth.signInWithOAuth({ provider: 'apple' });
Enter fullscreen mode Exit fullscreen mode

Magic Link (Passwordless)

// Send magic link
await supabase.auth.signInWithOtp({
  email: 'alice@example.com',
});
// User clicks link in email → logged in
Enter fullscreen mode Exit fullscreen mode

Session Management

// Listen for auth changes
supabase.auth.onAuthStateChange((event, session) => {
  switch (event) {
    case 'SIGNED_IN':
      console.log('User signed in:', session?.user.email);
      break;
    case 'SIGNED_OUT':
      console.log('User signed out');
      break;
    case 'TOKEN_REFRESHED':
      console.log('Token refreshed');
      break;
  }
});
Enter fullscreen mode Exit fullscreen mode

Row Level Security (RLS)

-- Users can only read their own data
CREATE POLICY "Users read own data" ON profiles
  FOR SELECT
  USING (auth.uid() = user_id);

-- Users can only update their own data
CREATE POLICY "Users update own data" ON profiles
  FOR UPDATE
  USING (auth.uid() = user_id);
Enter fullscreen mode Exit fullscreen mode

RLS policies ensure users can only access their own data — even if your frontend code has bugs.

React Hook

import { useEffect, useState } from 'react';
import { supabase } from './supabaseClient';
import { User } from '@supabase/supabase-js';

function useUser() {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    supabase.auth.getUser().then(({ data }) => {
      setUser(data.user);
      setLoading(false);
    });

    const { data: { subscription } } = supabase.auth.onAuthStateChange(
      (_, session) => setUser(session?.user ?? null)
    );

    return () => subscription.unsubscribe();
  }, []);

  return { user, loading };
}
Enter fullscreen mode Exit fullscreen mode

Supabase Auth vs Alternatives

Feature Supabase Auth Firebase Auth Clerk Auth0
Free MAU 50,000 10K (Spark) 10,000 7,500
Self-hosted Yes No No No
RLS Yes Security Rules No No
Social Providers 20+ 15+ 20+ 30+
Magic Links Yes Yes Yes Yes
Open Source Yes No No No

Need authenticated data extraction? Check out my Apify actors — secure scraping with API authentication. For custom solutions, email spinov001@gmail.com.

Top comments (0)