Does Supabase Work With Auth.js?

Partially CompatibleLast verified: 2026-02-26

You can use Supabase with Auth.js, but they're both full-featured auth solutions that require careful integration to avoid conflicts.

Quick Facts

Compatibility
partial
Setup Difficulty
Moderate
Official Integration
No — community maintained
Confidence
high
Minimum Versions
Supabase: 1.0.0
Auth.js: 5.0.0

How Supabase Works With Auth.js

Supabase and Auth.js are both complete authentication systems, which creates architectural tension. Supabase handles auth natively via PostgreSQL and its Auth service, while Auth.js provides abstracted auth logic across providers. The typical integration pattern is to use Auth.js as your session manager while delegating to Supabase as a custom provider or OAuth endpoint. You configure Auth.js with Supabase's OAuth credentials, letting Auth.js handle session state while Supabase manages user records. However, this means duplicating user data—Auth.js sessions don't automatically sync with Supabase's Auth tables. Alternatively, you can use Supabase Auth exclusively and skip Auth.js entirely, which is simpler. The hybrid approach works best when you need Auth.js's multi-provider orchestration (Google, GitHub, etc.) but want Supabase's PostgreSQL-backed user data and realtime capabilities. You'll need custom middleware to sync sessions and ensure both systems agree on user identity.

Best Use Cases

Multi-provider authentication (Google, GitHub, Discord) with Supabase database persistence and Row Level Security
Migrating from Auth.js to Supabase while maintaining existing session infrastructure during transition
Complex authorization rules that require Supabase RLS policies alongside Auth.js session management
Building real-time collaborative apps where Auth.js handles login flow but Supabase handles presence and data sync

Auth.js with Supabase as Custom Provider

bash
npm install next-auth @supabase/supabase-js
typescript
// auth.ts (NextAuth configuration)
import NextAuth from "next-auth";
import Credentials from "next-auth/providers/credentials";
import { createClient } from "@supabase/supabase-js";

const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_ANON_KEY);

export const { handlers, auth } = NextAuth({
  providers: [
    Credentials({
      name: "Supabase",
      credentials: {
        email: { label: "Email", type: "email" },
        password: { label: "Password", type: "password" },
      },
      async authorize(credentials) {
        const { data, error } = await supabase.auth.signInWithPassword({
          email: credentials.email as string,
          password: credentials.password as string,
        });

        if (error || !data.user) return null;

        return {
          id: data.user.id,
          email: data.user.email,
          name: data.user.user_metadata?.name,
        };
      },
    }),
  ],
  pages: { signIn: "/login" },
});

export { handlers as GET, handlers as POST };

Known Issues & Gotchas

critical

Session desynchronization between Auth.js and Supabase Auth tables

Fix: Use Auth.js as your single session source-of-truth and either disable Supabase Auth or sync sessions via webhook/middleware. Don't rely on Supabase Auth tables for user identity if Auth.js is your primary auth system.

warning

Supabase Auth service can revoke sessions independently, causing Auth.js to hold stale sessions

Fix: Implement session validation on each request by querying Supabase's auth status, or use Supabase Auth exclusively and bypass Auth.js for session management.

warning

OAuth provider configuration conflicts when using both systems

Fix: Configure OAuth providers only in Auth.js (not Supabase), or use Supabase's OAuth exclusively and treat Auth.js as a thin wrapper around it.

info

RLS policies reference Supabase Auth tables, but Auth.js manages sessions separately

Fix: Use a custom claim or JWT that includes the user ID, or sync Auth.js user IDs into a parallel Supabase Auth record.

Alternatives

  • Supabase Auth alone + Next.js middleware (simplest, no extra auth layer needed)
  • Auth.js with a custom database adapter (Prisma + PostgreSQL) instead of Supabase
  • Clerk with Supabase (better integration, Clerk handles sessions, Supabase handles data)

Resources

Related Compatibility Guides

Explore more compatibility guides