Skip to content
C.W.K.
Stream
Lesson 05 of 09 · published

Clerk & Supabase Auth

~18 min · Clerk, Supabase Auth, managed auth

Level 0Curious
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

When you'd use a managed auth service

Clerk and Supabase Auth absorb the auth UI, password resets, magic links, MFA, and session management. You write less code; you sign up for a vendor.

Comparison

FeatureAuth.js v5ClerkSupabase Auth
CostFree (self-hosted)Free tier; paid plansFree tier; paid plans
Setup timeMediumEasyMedium
Pre-built UINone (BYO)YesAuth UI package
DatabaseAny (adapter)ManagedPostgres included
Social providers80+20+20+

Picking

Clerk if you want zero auth UI work and accept the cost. Supabase if you also want the database and Row-Level Security from the same vendor. Auth.js if you want full control with no vendor.

Choose managed authentication when its maintained UI, recovery, MFA, and session operations are worth the vendor dependency. Compare export paths, pricing at the expected active-user count, organization support, regional requirements, and how authorization data reaches your application. Spend more time comparing account recovery and deletion than the happy-path login. Vendor cost includes how operators help locked-out users, what remains after deletion, and how non-portable credentials are handled during migration. Less authentication code does not mean less security design. Clerk or Supabase can establish identity, but your application still owns resource authorization, tenant boundaries, audit events, failure behavior, and the consequences of vendor downtime. Prototype sign-up, sign-in, sign-out, password or magic-link recovery, account deletion, and one protected mutation. Inspect cookies and server claims, revoke a session, simulate a provider outage, and document how user data would be exported.

Code

Clerk — matcher protects routes·ts
// proxy.ts
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';

const isProtected = createRouteMatcher(['/dashboard(.*)', '/api(.*)']);

export default clerkMiddleware((auth, req) => {
  if (isProtected(req)) auth().protect();
});
Supabase Auth — Server Component reads session·ts
// lib/supabase/server.ts
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';

export async function createClient() {
  const store = await cookies();
  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll: () => store.getAll(),
        setAll: (cs) => cs.forEach(({ name, value, options }) => store.set(name, value, options)),
      },
    }
  );
}

External links

Exercise

For your project, write a one-page decision: Auth.js, Clerk, or Supabase Auth? Cost, social providers needed, UI control, vendor risk. Pick one and justify.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.