next-auth vs Clerk: Picking React Auth for Your App
For React auth, the two real choices are nextauthjs/next-auth when you want self-hosted OAuth providers and session handling you fully control, and clerk/javascript when you'd rather hand off sign-in UI, user management, and MFA to a hosted service. Pick by how much auth code you want to own.
React auth tools split two jobs: proving who a user is and deciding what they can do. nextauthjs/next-auth is a Next.js library you wire into a route handler and call with useSession(). clerk/javascript ships prebuilt React components like <SignIn /> and <UserButton /> backed by a managed service. keycloak/keycloak is a separate Java server your React app talks to over OIDC, with its own admin console and realms.
nextauthjs/next-auth is the default choice for most React teams because most React teams are on Next.js. You add a catch-all handler at app/api/auth/[...nextauth], export a providers array, and useSession() works in client components while auth() works in server components. The 50+ OAuth providers, adapters for Prisma/Drizzle/Mongo, and the JWT-vs-DB session toggle mean next-auth scales from a side project to a real SaaS without rewriting.
clerk/javascript is the runner-up for teams that want polished auth UI without building it. clerk/javascript gives you <ClerkProvider>, <SignIn />, <UserButton />, and useUser() — sign-up flows, MFA, organizations, and a user admin panel come included, in exchange for a per-MAU bill. For specialists: supertokens/supertokens-core is the self-host answer to Clerk, and casbin/node-casbin handles RBAC/ABAC policy after auth is already solved.
If you're building a Next.js app and want OAuth working in an hour, pick nextauthjs/next-auth. If you want hosted prebuilt sign-in components and a user dashboard out of the box, pick clerk/javascript. If you need a full self-hosted identity server with realms, SAML, and an admin UI, pick keycloak/keycloak.
nextauthjs/next-auth is the default for any Next.js app. You drop in a catch-all route handler, list providers, and useSession() in components. It covers 50+ OAuth providers out of the box and lets you toggle between JWT and database sessions.
clerk/javascript is the runner-up when you want a hosted auth UI in an afternoon. Wrap the app in <ClerkProvider>, render <SignIn />, and call useUser() — you get sign-up, MFA, sessions, and a user dashboard without writing a backend.
nextauthjs
next-auth
- 28,311Stars
- 18Hotness
- 48Reliability
- over 8 yearsAge
nextauthjs/next-auth is an authentication library purpose-built for Next.js. You install next-auth, drop a catch-all route handler at app/api/auth/[...nextauth]/route.ts, export a list of providers and callbacks, then call useSession() in client components or auth() in server components and server actions. next-auth handles the OAuth callback exchange, CSRF tokens, encrypted cookie sessions, and a default sign-in page if you don't bring your own. Database adapters for Prisma, Drizzle, Mongoose, TypeORM, and DynamoDB persist users when you pick a DB session strategy instead of stateless JWTs.
Strengths: the provider catalog covers 50+ OAuth providers (Google, GitHub, Apple, Discord, Azure AD, Auth0) with one-line config; App Router and React Server Components support is first-class in v5; and the JWT-vs-database session toggle lets a hobby app and a multi-tenant SaaS use the same code. Drawbacks: the v4-to-v5 migration is real work and most older tutorials describe v4; the magical catch-all route can be opaque when an OAuth callback misfires; and outside Next.js (plain Vite + React Router) you'll fight the library more than help yourself.
Pick nextauthjs/next-auth when you're shipping a Next.js app and want OAuth working before lunch. If you're on a non-Next React SPA, pick authts/react-oidc-context instead. If you need a hosted UI and a user admin console without writing your own, pick clerk/javascript.
clerk
javascript
- 1,724Stars
- 9Hotness
- 1Reliability
- over 4 yearsAge
clerk/javascript is the official monorepo for Clerk's SDKs, including @clerk/clerk-react and @clerk/nextjs. You wrap your app in <ClerkProvider publishableKey="...">, drop <SignIn />, <SignUp />, <UserButton />, and <OrganizationSwitcher /> wherever you want auth UI to appear, and call useUser(), useAuth(), and useOrganization() to read state inside components. Clerk hosts the user database, the sign-in flows, and an admin dashboard at clerk.com — your React app and your backend talk to it over JWTs and a session cookie that Clerk's middleware verifies.
Strengths: the prebuilt components are genuinely production-quality — they handle MFA, passkeys, OAuth, magic links, email verification, and password reset without you writing any of those forms; the organizations + roles primitives map cleanly to B2B SaaS multi-tenancy; and the Next.js middleware integration (clerkMiddleware) does protected routes in one line. Drawbacks: clerk/javascript is open source but the service backing it is a paid SaaS once you pass the free MAU tier; data residency and full self-hosting aren't available; and deep customization beyond theming can mean rebuilding flows from primitives.
Pick clerk/javascript when you want auth, MFA, user management, and an admin dashboard without building any of it, and you're fine with a per-MAU bill. If you need self-hosted prebuilt UI, pick supertokens/supertokens-core. If you'd rather own the whole stack on Next.js, pick nextauthjs/next-auth.
goauthentik
authentik
- 22,387Stars
- 38Hotness
- 1Reliability
- over 6 yearsAge
goauthentik/authentik is a self-hosted identity provider written in Python (Django + Channels) with a Go-based outpost binary that proxies traffic to protected applications. The administrator builds authentication and authorization flows in a visual editor — stages like identification, password, MFA, consent — and binds them to providers (OIDC, SAML, proxy, LDAP). From React you almost always integrate via OIDC: configure an OIDC provider in goauthentik/authentik, then use authts/react-oidc-context or a vendor SDK on the client.
Strengths: the flow editor is the most flexible in the open-source IAM space — you can model recovery, enrollment, step-up auth, and conditional MFA as graphs without writing code; SAML, OIDC, LDAP, and proxy/forward-auth all live in one product; and the admin UI is modern and pleasant compared to Keycloak's. Drawbacks: it's a Python+Postgres+Redis stack with non-trivial operational footprint; flow misconfiguration can lock you out of your own admin; and the smaller community means fewer Stack Overflow answers than Keycloak.
Pick goauthentik/authentik when you want a modern self-hosted IdP with a visual flow editor for SSO and MFA. If you'd rather have Red Hat behind your IdP, pick keycloak/keycloak. If you only need front-of-proxy SSO without flow customization, pick authelia/authelia.
logto-io
logto
- 14,171Stars
- 31Hotness
- 84Reliability
- about 5 yearsAge
logto-io/logto is a modern self-hostable identity provider built on OIDC and OAuth 2.1, aimed squarely at SaaS and AI applications. It ships as a Node.js service with a Postgres backend, a prebuilt sign-in experience you can theme, and an admin console where you configure connectors (social, enterprise SSO, SAML), tenants/organizations, and RBAC roles. From a React SPA you install @logto/react, wrap your app in <LogtoProvider config={{ endpoint, appId }}>, and use useLogto() — { signIn, signOut, getIdTokenClaims, isAuthenticated } — to drive Authorization Code + PKCE.
Strengths: logto-io/logto bakes multi-tenancy and organizations in from day one, which is exactly what B2B SaaS needs and what older IdPs bolted on later; the sign-in UI is genuinely modern out of the box, so you don't immediately have to replace it; and the management API is well documented for programmatic tenant/role provisioning. Drawbacks: it's younger than Keycloak so the community and battle-tested integrations are smaller; enterprise SSO connectors and some advanced features are on the paid Logto Cloud tier; and SAML support has historically lagged OIDC features.
Pick logto-io/logto when you're building a multi-tenant SaaS and want a self-hostable, modern IdP with organizations built in. If you need deeper enterprise SAML/LDAP, pick keycloak/keycloak. If you want a fully managed React-component experience, pick clerk/javascript.
keycloak
keycloak
- 35,748Stars
- 31Hotness
- 60Reliability
- about 13 yearsAge
keycloak/keycloak is a full identity and access management server written in Java/Quarkus and run as a separate process (typically a container) that your React app talks to over OIDC. It ships a fully featured admin console where you create realms, register clients, define roles and groups, configure identity providers (Google, SAML IdPs, LDAP/AD), and write authentication flows as drag-and-drop graphs. From React you usually use keycloak-js or authts/react-oidc-context to drive the Authorization Code + PKCE flow against the Keycloak realm endpoint.
Strengths: keycloak/keycloak covers practically every enterprise auth scenario out of the box — SAML federation, LDAP/AD sync, fine-grained authorization with policies, custom user attributes, and a deep extension SPI for custom flows; the admin UI means non-developers can manage realms; and it's been Red Hat-maintained for over a decade. Drawbacks: it's a JVM service with real memory and startup-time costs, not something you bolt on lightly; the admin console is powerful but dated and easy to misconfigure; and you own the operational burden of running, upgrading, and backing up the database.
Pick keycloak/keycloak when you need full self-hosted SSO with SAML, LDAP, and an admin UI for an enterprise. If you want similar capabilities with a more modern stack, pick zitadel/zitadel or goauthentik/authentik. If you don't need an IdP and just want React auth, pick nextauthjs/next-auth.
authelia
authelia
- 28,331Stars
- 33Hotness
- 80Reliability
- over 9 yearsAge
authelia/authelia is a single sign-on and 2FA portal that sits in front of a reverse proxy (Traefik, nginx, Caddy, HAProxy) and protects whatever apps are behind it. The architecture is forward-auth: the proxy intercepts every request, asks authelia/authelia whether the session is valid, and either passes the request through or redirects the browser to authelia's login page. From a React app's perspective there's nothing to install — you just hit your normal URL and the proxy + Authelia handle login transparently before your bundle ever loads.
Strengths: authelia/authelia is the simplest way to put SSO and TOTP/WebAuthn 2FA in front of a homelab or small-business app stack — Authelia handles the login UI, the proxy enforces the rules, and your app stays oblivious; it federates against LDAP, file-based user DBs, or OIDC; and the YAML config is approachable. Drawbacks: it's not really a React-app library — if you want in-app sign-up flows, profile editing, or organizations you're in the wrong tool; the OIDC provider mode is younger than the forward-auth mode; and the model assumes a reverse proxy you control.
Pick authelia/authelia when you want to protect existing internal apps with SSO + MFA at the proxy layer. If you need an identity provider your app talks to directly via OIDC, pick keycloak/keycloak or zitadel/zitadel. If you need React-component-level auth, pick clerk/javascript.
ory
kratos
- 13,773Stars
- 21Hotness
- 1Reliability
- about 8 yearsAge
ory/kratos is a headless, cloud-native identity management server written in Go. Headless means it ships no UI — instead it exposes self-service flow APIs (registration, login, settings, recovery, verification, MFA) that your React app drives, rendering whatever screens fit your brand. You define identity schemas as JSON Schema, configure flows in YAML, and ory/kratos persists users in Postgres/MySQL/CockroachDB. For OAuth/OIDC issuance you pair it with Ory Hydra; for authorization you pair it with Ory Keto.
Strengths: ory/kratos scales horizontally and is genuinely engineered for billion-user deployments — Kubernetes-native, schema-driven, no UI lock-in; the flow API model means your React UI never sees passwords directly (the server orchestrates state); and the open-source license is permissive with a paid managed Ory Network if you don't want to run it. Drawbacks: headless means you write all the React forms yourself, which is a lot more work than dropping in <SignIn />; the flow state machine has a learning curve; and to get OIDC + RBAC + identity you end up running three Ory services, not one.
Pick ory/kratos when you need a self-hosted identity layer at serious scale and your design team will own the UI. If you'd rather have prebuilt screens, pick keycloak/keycloak or supertokens/supertokens-core. If you want a single managed service, pick clerk/javascript or zitadel/zitadel.
supabase
auth
- 2,501Stars
- 25Hotness
- 1Reliability
supabase/auth is the Go service (formerly known as GoTrue) that issues JWTs for every Supabase project. It exposes a REST API for sign-up, sign-in, magic-link, OTP, SAML, and OAuth flows, and stores users in a Postgres auth schema next to your application tables. From React you don't call supabase/auth directly — you call supabase.auth.signInWithPassword() through @supabase/supabase-js, which hits this server and stores the returned JWT in localStorage. Row-level security policies in Postgres read the JWT's sub claim, which is how authorization fans out.
Strengths: it's the same battle-tested service that powers every Supabase project, so OAuth providers, magic links, phone OTP, and MFA all work out of the box; the JWT integrates cleanly with Postgres RLS so authz becomes a SQL policy instead of middleware; and you can self-host the whole stack with docker-compose. Drawbacks: supabase/auth is really only interesting if you're already on Supabase Postgres — running it standalone gets you a JWT server with no UI; the React side depends on supabase-js conventions; and complex enterprise flows (SCIM, advanced SAML) lag behind Keycloak or Zitadel.
Pick supabase/auth when you're building on Supabase and want auth + DB + RLS as one story. If you need a fully self-hosted IAM with admin UI and realms, pick keycloak/keycloak. If you want a managed React-component experience instead, pick clerk/javascript.
zitadel
zitadel
- 14,464Stars
- 30Hotness
- 46Reliability
- over 6 yearsAge
zitadel/zitadel is a Go-based identity infrastructure platform you can self-host or consume as ZITADEL Cloud. The architecture is event-sourced — every identity action is an event in a Postgres or CockroachDB log, which makes audit trails and multi-region deployments tractable. It exposes OIDC, OAuth 2, SAML, and a gRPC + REST management API for tenants, organizations, projects, applications, roles, and users. From React you typically integrate via OIDC using authts/react-oidc-context, or via @zitadel/client for programmatic management calls from a backend.
Strengths: zitadel/zitadel ships multi-tenancy, organizations, projects, and fine-grained roles as first-class concepts, so B2B SaaS gets the data model right without bolting it on; passkeys/WebAuthn, OTP, and U2F are built in, not add-ons; and the event-sourced model makes audit logs and forensics painless. Drawbacks: it's newer than Keycloak so some enterprise SAML/SCIM edge cases are still maturing; running it well means understanding the event-store model; and the gRPC-first management API is less familiar than a REST admin console for ops teams.
Pick zitadel/zitadel when you want a modern, multi-tenant, self-hostable IdP with strong audit and passkey support. If you need the broadest battle-tested enterprise feature set, pick keycloak/keycloak. If you want a managed React-component experience instead, pick clerk/javascript.
supertokens
supertokens-core
- 15,213Stars
- 31Hotness
- 1Reliability
- over 6 yearsAge
supertokens/supertokens-core is a self-hostable auth backend you run as a Docker container alongside your app. The architecture is split: the Java core exposes a private API consumed by official Node, Go, and Python backend SDKs, which in turn talk to a React frontend SDK that renders prebuilt sign-in screens. In a Next.js or Express app you mount the supertokens middleware, configure a recipe (EmailPassword, ThirdParty, Passwordless, Session), and the React SDK exposes <SuperTokensWrapper>, useSessionContext(), and prebuilt <SignInAndUp /> screens you can theme.
Strengths: session management uses rotating refresh tokens with anti-CSRF and per-device revocation by default, which is hard to get right yourself; the recipe model lets you combine email/password, social, passwordless, and MFA without rewriting your client; and self-hosting is genuinely first-class — you bring your own MySQL or Postgres for user storage. Drawbacks: the core-plus-SDK split means more moving parts than next-auth; the prebuilt UI is functional but plainer than clerk/javascript's; and the managed cloud tier exists but isn't the headline product.
Pick supertokens/supertokens-core when you want Clerk-style prebuilt React UI but must self-host for compliance or cost. If you'd rather pay for a managed service, pick clerk/javascript. If you don't need prebuilt UI and live on Next.js, nextauthjs/next-auth is lighter.
firebase
firebase-js-sdk
- 5,135Stars
- 11Hotness
- 1Reliability
- about 9 yearsAge
firebase/firebase-js-sdk is Google's official JavaScript SDK for the entire Firebase platform — Auth is one product among many in the same monorepo. For auth you import { getAuth, signInWithEmailAndPassword, signInWithPopup, GoogleAuthProvider } from 'firebase/auth', initialize the app with your config, and call signInWithPopup(auth, new GoogleAuthProvider()) from a React component. onAuthStateChanged(auth, user => ...) gives you a subscription you wire into a React context or useSyncExternalStore. Tokens are JWTs you forward to your backend or to Firestore security rules.
Strengths: it's the lowest-friction way to ship auth + Firestore + Cloud Storage together — one config, one SDK, one bill; OAuth providers, email link, phone OTP, and anonymous auth all work out of the box; and the modular v9+ SDK is tree-shakeable so your React bundle stays reasonable. Drawbacks: firebase/firebase-js-sdk is deeply tied to Google Cloud — you can't really self-host; the auth UI is bring-your-own unless you adopt FirebaseUI; and once you outgrow Firestore security rules, the authorization model gets awkward.
Pick firebase/firebase-js-sdk when you're building on Firebase/Firestore and want auth to come along for free. If you want a similar full-stack story without Google, pick supabase/auth. If you want managed auth without committing to a backend, pick clerk/javascript.
panva
node-oidc-provider
- 3,777Stars
- 5Hotness
- 64Reliability
- over 10 yearsAge
panva/node-oidc-provider is a certified OpenID Connect and OAuth 2.0 Authorization Server you embed inside a Node.js process — it is what you reach for when you want to be the identity provider, not consume one. You import Provider from 'oidc-provider', construct it with your issuer URL, supported clients, claims, scopes, and an account adapter (you implement findAccount(ctx, id)), then mount provider.callback() into Express, Koa, Fastify, or Next.js route handlers. From a React SPA you never import panva/node-oidc-provider directly — your React app talks to it over standard OIDC via authts/react-oidc-context or auth0/auth0-react-style SDKs.
Strengths: it is OpenID Certified across the discovery, dynamic client registration, and FAPI profiles, so any compliant client (including iOS/Android SDKs) works out of the box; the API gives you total control of consent screens, token formats, claims, and grant types; and it's maintained by Filip Skokan, who is also behind jose and openid-client. Drawbacks: this is a low-level library, not a product — you write the UI, the user store, the admin console, and the password reset flows yourself; misconfiguring an OIDC server has security consequences; and the learning curve assumes you already know the spec.
Pick panva/node-oidc-provider when you're building your own identity product or embedding an OIDC server into an existing Node platform. If you want a packaged IdP instead, pick keycloak/keycloak, zitadel/zitadel, or logto-io/logto.
aws-amplify
amplify-js
- 9,562Stars
- 1Hotness
- 1Reliability
- almost 9 yearsAge
aws-amplify/amplify-js is AWS's declarative client library that wraps Cognito, AppSync, S3, Pinpoint, and a dozen other AWS services behind a unified JavaScript API. For auth you import { Amplify } from 'aws-amplify' plus { signIn, signUp, confirmSignIn, getCurrentUser, signOut } from 'aws-amplify/auth', call Amplify.configure with your Cognito User Pool and Identity Pool IDs, and drive the flows directly. The optional @aws-amplify/ui-react package gives you <Authenticator> — a prebuilt React component that renders the whole sign-in / sign-up / MFA flow against your User Pool.
Strengths: aws-amplify/amplify-js is the official, supported way to put a React app on top of Cognito and federate identities into IAM-protected AWS resources; the <Authenticator> component is a real time-saver versus calling Cognito APIs by hand; and you get S3 uploads, AppSync subscriptions, and analytics in the same SDK. Drawbacks: it locks you to AWS — Cognito's user model and quotas have rough edges and migrating off later is painful; the SDK is heavy and the API has been rewritten across major versions; and Cognito's customization story (hosted UI vs custom UI vs Amplify UI) is genuinely confusing.
Pick aws-amplify/amplify-js when your stack is committed to AWS and you want Cognito + S3 + AppSync in one SDK. If you want managed auth without AWS lock-in, pick clerk/javascript. If you want a self-hosted alternative to Cognito, pick zitadel/zitadel or keycloak/keycloak.
auth0
auth0-react
- 988Stars
- 2Hotness
- 1Reliability
- about 6 yearsAge
auth0/auth0-react is the official React SDK for Okta's Auth0 identity platform. It wraps @auth0/auth0-spa-js and exposes <Auth0Provider domain="..." clientId="..." authorizationParams={{ redirect_uri }}> plus useAuth0(), which returns { isAuthenticated, user, loginWithRedirect, logout, getAccessTokenSilently }. Behind the scenes it runs the OIDC Authorization Code + PKCE flow against your Auth0 tenant, caches tokens in memory or web storage, and silently renews them via refresh tokens or iframe. Your backend validates the JWT against Auth0's JWKS endpoint.
Strengths: auth0/auth0-react is the path of least resistance if you're already paying for an Auth0 tenant — social and enterprise connections, MFA, anomaly detection, and rules/actions all live in the Auth0 dashboard, not your code; the SDK is stable and well documented; and Auth0's Universal Login means you don't write sign-in UI at all. Drawbacks: it locks you to one identity provider (Auth0/Okta) and one pricing model; the SaaS bill scales steeply past hobby tier; and customization beyond Universal Login often means writing actions in Auth0's runtime.
Pick auth0/auth0-react when your org already uses Auth0 and you want the official, supported React integration. If you'd rather not lock to a vendor, pick authts/react-oidc-context against any OIDC provider. If you want hosted UI without Auth0's pricing, pick clerk/javascript.
casbin
node-casbin
- 2,905Stars
casbin/node-casbin is an authorization library, not an authentication library — it answers "can user U do action A on resource R?" after some other system has told you who U is. The architecture is two files: a model.conf describing your access pattern (ACL, RBAC, RBAC with domains, ABAC, RESTful) in a tiny DSL, and a policy.csv (or DB-backed adapter) listing the actual rules. In a Node backend you call await enforcer.enforce(sub, obj, act) on every protected operation; from React you typically don't call casbin/node-casbin directly — your API server does, and returns a boolean.
Strengths: the model/policy split means you can change your authorization scheme (flat RBAC → RBAC with tenants → ABAC with conditions) without rewriting application code; adapters exist for Postgres, MySQL, MongoDB, Redis, and most other stores; and the model language is the same across Casbin's Go, Java, Python, and PHP ports, so polyglot teams share policies. Drawbacks: it's authorization-only — you still need next-auth, Clerk, Keycloak, or similar for who-is-this-user; the DSL has a learning curve; and performance on huge policy sets needs indexed adapters.
Pick casbin/node-casbin when your React app already has auth solved and you need a real RBAC/ABAC policy engine on the backend. If you need both auth and authz in one product, pick keycloak/keycloak or zitadel/zitadel.
authts
react-oidc-context
- 1,022Stars
authts/react-oidc-context is a thin React wrapper around oidc-client-ts, the maintained successor to the original IdentityModel oidc-client-js. The architecture is small on purpose: you wrap your app in <AuthProvider authority="..." client_id="..." redirect_uri="..."/>, and inside any component useAuth() returns { isAuthenticated, user, signinRedirect, signoutRedirect, isLoading }. The provider performs the OIDC Authorization Code + PKCE flow against any compliant identity provider, handles silent token renewal via iframe or refresh token, and stores tokens in sessionStorage by default.
Strengths: it's the standards-correct way to talk to any OIDC provider from a React SPA — Keycloak, Auth0, Okta, Azure AD, Ory, Zitadel all just work; the API surface is tiny (one provider, one hook) and easy to reason about; and unlike vendor SDKs you aren't locked into one identity provider. Drawbacks: authts/react-oidc-context only handles the client side — you still need a real OIDC server somewhere; it ships no UI components, so sign-in screens are whatever your IdP renders; and SSR and Next.js App Router integration needs care because window-bound storage isn't available server-side.
Pick authts/react-oidc-context when you have an existing OIDC provider (Keycloak, Okta, Azure AD) and want a clean React-SPA client. If you need the provider too and are on Next.js, pick nextauthjs/next-auth. If you want hosted UI plus React components, pick clerk/javascript.
