Skip to main content

Authentication for Indie Hackers: Clerk vs Auth0 vs NextAuth

A practical comparison to help indie hackers choose an auth solution for their MVPs

Published: December 9, 2025 Updated: May 25, 2026 Larry Qu 11 min read

Introduction

Authentication is a critical part of most SaaS apps, but writing it from scratch adds risk and delays. Choose a solution that balances security, developer experience, and cost. This guide compares Clerk, Auth0, and NextAuth and offers recommendations based on your project needs.


Comparison Summary

  • Clerk: Great for product-focused teams; rich UI components, magic links, and social sign-in
  • Auth0: Enterprise-ready, flexible, and secure; but can be expensive for small projects
  • NextAuth (Auth.js): Open-source, flexible for Next.js projects; requires more wiring but low cost
  • Supabase Auth: Built-in with Supabase, free generous tier, row-level security integration
  • Firebase Auth: Google-backed, massive ecosystem, free tier up to 10K users/month
  • Lucia: Lightweight auth library, full control, minimal dependencies

Core Considerations

  • Developer Experience (DX): How quickly can you ship auth flows?
  • Pricing: Free tier limits and growth cost
  • Security: MFA, session handling, passwordless, SSO
  • UI: Hosted UI vs self-managed UI
  • Compliance: GDPR, SOC2 (if needed)

Provider Comparison Table

Provider Free Tier Paid From MFA SSO Passkeys Hosted UI Open Source Best For
Clerk 10K MAU 10K+ MAU Yes (paid) Yes (paid) Yes Yes No Fast shipping, built-in UI
Auth0 7K users $30/mo Yes Yes (paid) No Yes Yes Enterprise, SSO, compliance
NextAuth Unlimited DB costs only Via providers Via providers No No Yes Next.js, full control
Supabase Auth 50K MAU $25/mo Yes (preview) No No Yes (basic) Yes Supabase ecosystem
Firebase Auth 10K users $0.02/verify Yes No No Yes Partially Google ecosystem
Lucia Unlimited DB costs only Manual Manual No No Yes Custom auth, full control

Overview of Additional Providers

Supabase Auth integrates natively with Supabase’s PostgreSQL, providing built-in row-level security (RLS). User management and sessions are handled automatically. Best for indie hackers already using Supabase for their database.

Firebase Auth offers Google-first auth with extensive platform support (iOS, Android, Web). Free tier supports up to 10K monthly active users. Authentication methods include email/password, phone auth, and social providers. Deep Google Cloud integration enables serverless auth with Firebase Functions.

Lucia is a lightweight, unopinionated auth library for TypeScript. It provides session management, email/password auth, and OAuth. Unlike full-featured providers, you control every aspect of the auth flow. It pairs well with databases like SQLite, PostgreSQL, and MySQL. Best for developers who want minimal dependencies and complete flexibility.


Clerk: Pros & Cons

Pros:

  • Prebuilt UIs for sign-in, sign-up, and profile management
  • Passwordless and social login by default
  • Good developer experience and SDKs for modern frameworks

Cons:

  • Paid plans kick in quickly as users grow
  • Less flexibility for complex enterprise flows

Best for: Indie hackers who want to ship fast with secure auth and minimal custom UI work


Auth0: Pros & Cons

Pros:

  • Very flexible and powerful (SSO, MFA, enterprise features)
  • Mature documentation and enterprise readiness

Cons:

  • Can be expensive; pricing is complex
  • Requires more configuration than Clerk

Best for: When you need enterprise authentication, SSO, or advanced compliance features


NextAuth: Pros & Cons

Pros:

  • Open-source and free to use
  • Tight integration with Next.js
  • Flexible and extensible with adapters (e.g., Prisma)

Cons:

  • You manage session security and UI
  • More dev time for custom flows

Best for: Projects built with Next.js where you want full control and low cost


Implementation Patterns by Stack

Quick MVP — Clerk (Next.js)

  1. Install @clerk/nextjs
  2. Wrap your app in <ClerkProvider>
  3. Use <SignedIn> and <SignedOut> components to conditionally render UI
  4. Access user data via useUser() hook
  5. Protect API routes with auth() middleware
// layout.tsx
import { ClerkProvider, SignedIn, SignedOut, UserButton } from '@clerk/nextjs'
import Link from 'next/link'

export default function RootLayout({ children }) {
  return (
    <ClerkProvider>
      <header>
        <SignedOut><Link href="/sign-in">Sign In</Link></SignedOut>
        <SignedIn><UserButton afterSignOutUrl="/" /></SignedIn>
      </header>
      <main>{children}</main>
    </ClerkProvider>
  )
}

Strengths: Zero UI work. Works in 30 minutes. Includes dark mode, localization. Weaknesses: Paid tiers escalate quickly. Limited customization of auth flows.

Cost-Conscious — NextAuth with Prisma

  1. Install next-auth and @auth/prisma-adapter
  2. Configure [...nextauth].ts with providers and adapter
  3. Create custom sign-in/sign-up pages
  4. Use useSession() and getServerSession() for session access
  5. Manage session database with Prisma migrations
// app/api/auth/[...nextauth]/route.ts
import NextAuth from 'next-auth'
import GitHub from 'next-auth/providers/github'
import Google from 'next-auth/providers/google'
import { PrismaAdapter } from '@auth/prisma-adapter'
import { prisma } from '@/lib/prisma'

export const { handlers, signIn, signOut, auth } = NextAuth({
  adapter: PrismaAdapter(prisma),
  providers: [
    GitHub({ clientId: process.env.GITHUB_ID!, clientSecret: process.env.GITHUB_SECRET! }),
    Google({ clientId: process.env.GOOGLE_ID!, clientSecret: process.env.GOOGLE_SECRET! }),
  ],
  pages: { signIn: '/auth/signin' },
  callbacks: {
    session({ session, user }) { session.user.id = user.id; return session }
  }
})

Strengths: Free, full control, extensible with custom providers. Weaknesses: Requires building auth UI, managing sessions, and handling security yourself.

Enterprise-Ready — Auth0

  1. Create Auth0 tenant and configure connections
  2. Install @auth0/nextjs-auth0 SDK
  3. Set up universal login flow
  4. Configure roles, permissions, and MFA in dashboard
  5. Integrate with enterprise SSO (SAML, OIDC, LDAP)
// app/page.tsx
import { getSession } from '@auth0/nextjs-auth0'
import Link from 'next/link'

export default async function Home() {
  const session = await getSession()
  return (
    <nav>
      {session ? (
        <Link href="/api/auth/logout">Logout ({session.user.name})</Link>
      ) : (
        <Link href="/api/auth/login">Login</Link>
      )}
    </nav>
  )
}

Strengths: Enterprise features out of box. SOC2 compliant. Extensive documentation. Weaknesses: Pricing scales fast. Complex configuration for basic flows.

Supabase Auth (PostgreSQL-native)

  1. Initialize Supabase client with @supabase/supabase-js
  2. Use supabase.auth.signUp() and signIn() methods
  3. Configure RLS policies for database security
  4. Use supabase.auth.onAuthStateChange() for session management
// lib/supabase.ts
import { createClient } from '@supabase/supabase-js'

export const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)

// app/page.tsx (client component)
const { data: { user } } = await supabase.auth.getUser()
if (user) {
  // Query user-specific data via RLS policies
  const { data } = await supabase.from('projects').select('*')
}

Strengths: Free up to 50K MAU. Tight PostgreSQL integration. RLS ensures security at database level. Weaknesses: Limited social providers. No built-in SSO. Less mature than dedicated auth providers.

Lightweight Control — Lucia

  1. Install lucia and database adapter
  2. Initialize Lucia with your database connection
  3. Create auth API routes for signup, login, logout
  4. Build custom session management
// lib/auth.ts
import { Lucia } from 'lucia'
import { PrismaAdapter } from '@lucia-auth/adapter-prisma'
import { prisma } from './prisma'

export const lucia = new Lucia(new PrismaAdapter(prisma.session, prisma.user))

export type Auth = typeof lucia

Strengths: Minimal dependencies, full control, TypeScript-first, works with any framework. Weaknesses: You build everything. No UI components. Security responsibility entirely on you.



Pricing Comparison for Indie Hackers

Pricing is often the deciding factor for bootstrapped founders. Here’s the real-world cost at different stages:

Provider MVP Stage (0-100 users) Growth Stage (1K-10K users) Scale Stage (10K+ users)
Clerk Free $25-50/mo $100-500/mo+
Auth0 Free (7K users) $30-100/mo Enterprise pricing
NextAuth Free (DB cost: $5-30/mo) Free (DB cost: $30-100/mo) Free (DB cost scales)
Supabase Auth Free (50K MAU) $25/mo $100-500/mo+
Firebase Auth Free (10K users) $0.02/verification Custom pricing
Lucia Free (DB cost: $5-30/mo) Free (DB cost: $30-100/mo) Free (DB cost scales)

Cost efficiency ranking for indie hackers:

  1. Lucia / NextAuth — lowest cost, highest effort
  2. Supabase Auth — generous free tier, great value
  3. Clerk — reasonable for early stage, escalates
  4. Firebase Auth — good free tier, can get expensive at scale
  5. Auth0 — best value at enterprise, expensive for indie

User Management Features

Beyond authentication, user management infrastructure affects your daily operations.

Built-in user admin dashboard:

  • Clerk: User management portal included. Search, filter, impersonate users. Manage sessions and roles. No build required.
  • Auth0: Comprehensive dashboard for users, roles, logs, and rules. Extensive but complex.
  • NextAuth: No dashboard. Build your own admin panel or use a third-party tool.
  • Supabase Auth: Basic user management in Supabase dashboard. Limited but functional.
  • Firebase Auth: User management in Firebase console. Basic search and disable/enable.
  • Lucia: No dashboard. Full DIY approach.

User profile enrichment:

  • Clerk and Auth0 support custom user metadata, organization membership, and webhook events for user lifecycle.
  • Supabase and Firebase provide basic profile fields but require custom implementation for complex data.
  • NextAuth and Lucia give you raw database access—build whatever profile structure you need.

MFA, SSO, and Passkeys

Authentication security requirements evolve as your product grows.

Multi-Factor Authentication (MFA)

  • Clerk: MFA with TOTP (authenticator apps) and SMS. Available on paid plans.
  • Auth0: Comprehensive MFA including TOTP, SMS, push notifications, and WebAuthn. Configurable risk-based MFA triggers.
  • NextAuth: No built-in MFA. Implement via custom provider or third-party service (workos, descope).
  • Supabase Auth: MFA in preview (TOTP). Actively being developed.
  • Firebase Auth: MFA with TOTP and SMS. Native SDK support.
  • Lucia: No built-in MFA. Implement from scratch or integrate an MFA library.

Single Sign-On (SSO)

SSO enables enterprise customers to use their corporate identity providers (Okta, Azure AD, Google Workspace).

  • Auth0 and Clerk: Enterprise SSO through SAML/OIDC. Auth0 has deeper support for complex enterprise configurations.
  • NextAuth: SSO via generic OAuth/OIDC provider. Works with any standard-compliant IDP but requires configuration.
  • Supabase Auth and Firebase Auth: Limited or no enterprise SSO. Not suitable for B2B enterprise products.
  • Lucia: No SSO. Build your own OIDC integration.

Passkeys

Passkeys (WebAuthn) are the emerging standard for passwordless authentication. They replace passwords with biometric authentication on user devices.

  • Clerk: Built-in passkey support on paid plans. Simple toggle in dashboard.
  • Auth0: Passkey support in preview. Available through custom actions.
  • NextAuth: No native passkey support. Implement via WebAuthn library (@simplewebauthn/server).
  • Supabase Auth: Passkeys not yet supported. Rely on passwordless email links instead.
  • Firebase Auth: Passkey support through Google Identity Services.
  • Lucia: No passkey support. DIY with WebAuthn libraries.

Migration Between Providers

Migrating auth providers is painful but sometimes necessary as requirements change. Plan migration strategy upfront.

Common Migration Patterns

From host-based (Clerk, Auth0) to NextAuth/Lucia:

  • Export user data (email, hashed passwords, metadata) from the provider’s dashboard or API.
  • Import users into your new database with hashed passwords preserved (if using same algorithm).
  • Force password reset for all migrated users on first login.
  • Run both auth systems in parallel during transition, using feature flags to migrate users gradually.

Database migration considerations:

  • User IDs must remain consistent to preserve data relationships.
  • Session tokens will be invalidated. All users must re-login after migration.
  • Notify users about the migration 2 weeks in advance.
  • Plan for 1-2 days of full-stack testing before cutover.

Migration Cost-Benefit

Migrate To Migration Difficulty Benefit
Clerk from anything Medium Better DX, features
Auth0 from anything Medium-High Enterprise features, SSO
NextAuth from anything Medium Lower cost, full control
Supabase from Firebase Medium Lower cost, PostgreSQL RLS
Lucia from anything High Maximum flexibility, zero vendor lock-in

Security Considerations

Authentication security mistakes are the most common vulnerability in indie products.

Session Security

  • Use JWTs with short expiration (15-60 minutes) and refresh tokens for extending sessions.
  • Store tokens in httpOnly cookies, not localStorage (which is vulnerable to XSS).
  • Implement CSRF protection for all auth-related endpoints.
  • Rotate session IDs after login to prevent session fixation attacks.
  • Set session timeouts: inactive sessions expire after 7 days, absolute maximum 30 days.

Password Policies

  • Minimum 8 characters, no maximum.
  • Ban common passwords (use a library like zxcvbn to check password strength).
  • Hash passwords with bcrypt (cost factor 12+) or Argon2id.
  • Never store plaintext passwords. Never transmit passwords over unencrypted connections.
  • Implement rate limiting: 5 failed login attempts triggers a 15-minute lockout.

OAuth Security

  • Validate state parameters to prevent CSRF in OAuth flows.
  • Use PKCE (Proof Key for Code Exchange) for mobile and SPA OAuth flows.
  • Verify the iss claim in JWT tokens from OAuth providers.
  • Never log tokens or authorization codes.

API Protection

  • Authenticate all API routes. Use middleware to enforce auth globally.
  • Implement proper CORS policies. Don’t use Access-Control-Allow-Origin: * for authenticated endpoints.
  • Use API rate limiting to prevent brute force attacks on auth endpoints.
  • Log authentication events (successful logins, failed attempts, password resets) for security auditing.

Compliance Basics

  • GDPR: Provide user data export and account deletion. Document data processing. Obtain consent for cookies and tracking.
  • SOC2: Required for B2B enterprise deals. Auth0 and Clerk offer SOC2 reports. Self-managed solutions require external audit.
  • CCPA: If serving California users, support data deletion requests and opt-out mechanisms.

Recommendations by Use Case

Use Case Recommended Provider Runner Up
Quick MVP, need to ship today Clerk Supabase Auth
Next.js project, want full control NextAuth (Auth.js) Lucia
Enterprise B2B SaaS Auth0 Clerk (Enterprise plan)
Supabase project, PostgreSQL data Supabase Auth NextAuth with Prisma
Maximum cost savings NextAuth Lucia
Google-first ecosystem Firebase Auth Supabase Auth
Learning auth internals Lucia NextAuth

Final Thoughts

Authentication is a solved problem, but each approach presents tradeoffs. For indie hackers launching an MVP, speed and developer experience often win. Start simple and iterate: use hosted solutions for early users and migrate to flexible or managed solutions when you need them.

Action: Pick your stack and implement sign-up/login this week—move quickly and test the user flow with early users. The perfect auth solution doesn’t exist. Pick the one that removes friction from your current stage and plan to evolve as you grow.


Demonstration GIFs & recording

If you plan to create a quick demo or GIF (sign-up flow, profile updates), follow /assets/gif-instructions/README.md to record a terminal or screen and convert it to a GIF. Suggested recording steps:

  1. Record: Start a dev server and walk through sign-up with test accounts
  2. Cropping: Focus on the browser window for the sign-up + redirect
  3. Convert: Use the scripted ffmpeg steps to produce an optimized GIF

Comments

👍 Was this article helpful?