@seamless-auth/react is a React SDK for Seamless Auth. It gives you a provider for auth state, a headless client and hooks for custom auth UIs, and optional prebuilt auth routes when you want a faster drop-in flow.
AuthProviderAuthRoutesuseAuth()createSeamlessAuthClient()useAuthClient()usePasskeySupport()- types including
AuthMode,AuthContextType,Credential,User, and the headless client input/result types
npm install @seamless-auth/reactYou can use this package in three ways:
AuthProvider+useAuth()for auth state and core auth actionscreateSeamlessAuthClient()oruseAuthClient()to build fully custom login and registration screensAuthRouteswhen you want the built-in login, OTP, magic-link, and passkey screens
Most apps will use AuthProvider either way.
import { AuthProvider } from '@seamless-auth/react';
import { BrowserRouter } from 'react-router-dom';
<BrowserRouter>
<AuthProvider apiHost="https://your.api" mode="server">
<AppRoutes />
</AuthProvider>
</BrowserRouter>;import { useAuth } from '@seamless-auth/react';
function Dashboard() {
const { user, logout, refreshSession } = useAuth();
return (
<div>
<p>Welcome, {user?.email}</p>
<button onClick={() => void refreshSession()}>Refresh session</button>
<button onClick={() => void logout()}>Logout</button>
</div>
);
}import { AuthRoutes, useAuth } from '@seamless-auth/react';
import { Route, Routes } from 'react-router-dom';
function AppRoutes() {
const { isAuthenticated } = useAuth();
return (
<Routes>
{isAuthenticated ? (
<Route path="*" element={<Dashboard />} />
) : (
<Route path="*" element={<AuthRoutes />} />
)}
</Routes>
);
}You are still responsible for your app’s route protection and redirects.
useAuth() returns the current auth state plus the provider-backed helpers:
{
user: User | null;
credentials: Credential[];
isAuthenticated: boolean;
loading: boolean;
apiHost: string;
mode: AuthMode;
hasSignedInBefore: boolean;
markSignedIn(): void;
hasRole(role: string): boolean | undefined;
refreshSession(): Promise<void>;
logout(): Promise<void>;
deleteUser(): Promise<void>;
login(identifier: string, passkeyAvailable: boolean): Promise<Response>;
handlePasskeyLogin(): Promise<boolean>;
updateCredential(credential: Credential): Promise<Credential>;
deleteCredential(credentialId: string): Promise<void>;
}Use refreshSession() after completing a custom auth flow that should update provider state.
For custom auth UIs, use the exported client directly:
import { createSeamlessAuthClient } from '@seamless-auth/react';
const authClient = createSeamlessAuthClient({
apiHost: 'https://your.api',
mode: 'server',
});
const response = await authClient.login({
identifier: 'user@example.com',
passkeyAvailable: true,
});
if (response.ok) {
// Continue your custom flow
}The headless client exposes helpers for:
- current-user/session lookup
- login and passkey login
- registration
- phone OTP and email OTP
- magic-link request, verify, and polling
- passkey registration
- logout and delete-user
- credential update and deletion
Client methods return raw Response objects except for the passkey convenience helpers:
loginWithPasskey(): Promise<PasskeyLoginResult>registerPasskey(metadata): Promise<PasskeyRegistrationResult>
If you want custom React screens but do not want to manually recreate the client, use the exported hooks:
import { useAuth, useAuthClient, usePasskeySupport } from '@seamless-auth/react';
function CustomLogin() {
const { refreshSession } = useAuth();
const authClient = useAuthClient();
const { passkeySupported, loading } = usePasskeySupport();
async function handleEmailLogin() {
const response = await authClient.login({
identifier: 'user@example.com',
passkeyAvailable: passkeySupported,
});
if (response.ok) {
await refreshSession();
}
}
return (
<button disabled={loading} onClick={() => void handleEmailLogin()}>
Sign in
</button>
);
}AuthRoutes currently includes:
/login/passKeyLogin/verifyPhoneOTP/verifyEmailOTP/verify-magiclink/registerPasskey/magiclinks-sent
These are optional UI wrappers over the same SDK primitives the package now exports for custom flows.
This package assumes a Seamless Auth-compatible backend with cookie-based auth flows.
- In
webmode, requests target${apiHost}/... - In
servermode, requests target${apiHost}/auth/... - Requests are sent with
credentials: 'include' AuthProvidervalidates the current session by calling/users/meon load
The built-in flows assume compatible endpoints for:
/login/logout/registration/register/webAuthn/login/start/webAuthn/login/finish/webAuthn/register/start/webAuthn/register/finish/otp/generate-phone-otp/otp/generate-email-otp/otp/verify-phone-otp/otp/verify-email-otp/magic-link/magic-link/check/magic-link/verify/:token/users/me/users/credentials/users/delete
- This package does not create its own
<BrowserRouter>. - It is designed to fit into your app’s existing routing tree.
- The quickest path is
AuthProvider+AuthRoutes. - The most flexible path is
AuthProvider+ custom UI usinguseAuth(),useAuthClient(), andusePasskeySupport().
AGPL-3.0-only