Every Next.js project eventually needs the same thing: a way to know who's logged in. Three approaches dominate the ecosystem today, and they solve the problem very differently.
Auth.js (formerly NextAuth.js)
Open-source and framework-native. You own the session logic and the database schema; Auth.js just wires up the OAuth flows and JWT/session handling. That control is the appeal — and the cost. There's no hosted dashboard, no built-in user management UI, and you're responsible for keeping the adapter and provider configs current as the library evolves.
Clerk
A fully hosted auth product: drop-in React components, a hosted user management dashboard, and built-in support for organizations and multi-factor auth. The trade-off is the same one every hosted service makes — you're depending on a third party for something as central as login, and migrating off it later means rebuilding the pieces Clerk gave you for free.
Supabase Auth
Bundled with Supabase's Postgres database and row-level security, so auth and data access rules live in the same place. A natural fit if you're already on Supabase; less compelling as a standalone choice if you're not.
Which one is right?
There's no universal answer — it depends on how much of the auth stack you want to own versus rent, and whether you're already committed to a backend that one of these integrates with more naturally than the others. What matters is picking based on the actual trade-offs, not marketing copy.