Overview
Logto auth for a Convex React app. The Convex deployment holds the Logto credentials; the browser holds a short-lived ID token.
Use Logto (self-hosted or cloud) as the auth provider for a Convex React app.
What you get
- One provider on the frontend.
<ConvexLogtoSessionProvider>signs in, finishes the callback, refreshes, and signs out. No Logto SDK in the bundle and no hand-rolleduseAuthbridge. - One line on the backend.
logtoAuthConfig()reads your env. No JWT template, no algorithm, no JWKS URL to copy. - Every Logto value on the Convex deployment. Endpoint, app id, and app
secret live in
npx convex env. The frontend build carries none of them; the only per-environment value in the bundle is the Convex URL. - Revoked sessions sign out at once. A sign-out on another device, "sign out everywhere", a suspension, or an admin ending the session reaches every open tab through a Convex subscription, without waiting for the ID token to expire.
Not sure this is the right package for you? Why this package
compares it with @convex-dev/auth, Clerk, and wiring Logto by hand, and says
when each of those is the better answer.
Two modes
Session mode is the recommended path and what the Quick start sets up. Your Convex deployment is the OAuth client. A Convex component holds the Logto refresh token in tables your app code cannot read, and the browser holds a short-lived ID token plus a rotating application session token.
Bridge mode puts Logto's SPA SDK (@logto/react) in
the browser and bridges its ID token into Convex. Zero server-side state, and
the refresh token lives in localStorage. Pick it when you want no server
state at all, or when you already run it. It stays supported.
Both modes present the same ID token to Convex, so ctx.auth.getUserIdentity(),
webhook sync, and organization
authorization work the same.
Moving between them is a new Logto app and a provider swap. Whichever mode you
choose, apply the SPA security baseline to the code
that shares the browser origin with authentication.
ID token over OIDC
The package hands Convex Logto's ID token, so Convex discovers the signing key and JWKS itself. The one Logto-side requirement is an RSA OIDC signing key. Convex rejects Logto's default ES384 without an error, so rotate the key once per tenant before anything else; the Quick start starts there.
Install
pnpm add convex-logtoconvex and react are peers you already have. Bridge mode adds
@logto/react (@logto/rn on Expo); Expo session mode adds
expo-secure-store and expo-web-browser.
Where to next
Get started
- Quick start: session mode on Vite, end to end, in six steps.
- Bridge mode: the same six steps with the Logto SDK in the browser.
Integrations, where the provider mounts and where the callback goes:
Guides
- Session mode: the threat model, the device list, device binding, the HttpOnly cookie transport, and what happens when a refresh fails.
- Auth in your app: render and route on auth state.
- Webhook sync: mirror Logto users into a queryable Convex table.
- Back-channel logout: let Logto end sessions from its side.
- SPA security baseline: CSP, Trusted Types, third-party script hygiene, and least-privilege scopes.
- Multiple environments: dev / staging / prod.
Reference
- API reference: every export and its signature.
- How it works: why the ID token, why there's no JWT config, and the one Convex client option to turn on.
Examples
Runnable apps you can copy from. Each wires the same package for a different framework:
Vite + React, session mode
The quick start as an app: server-held refresh token, device list, live revocation.
Next.js App Router, session mode
HttpOnly cookie transport, server rendering with a real identity, document-only refresh in the proxy.
Expo, session mode
SecureStore credentials, deep-link sign-in, reclaimed-sign-in recovery.
Vite + React, bridge mode
One provider, static config, declarative auth gating.
TanStack Router (SPA), bridge mode
Route guards in beforeLoad, plus a webhook-synced users table with RBAC.
TanStack Start (SSR), bridge mode
One SSR-safe provider and beforeLoad route guards.
Next.js App Router, bridge mode
Client provider boundary and a callback route.
Expo, bridge mode
convex-logto/native on @logto/rn, no callback route.