Building with the SDK
React
Hooks, control components and the provider.
npm install @zevauth/react
Everything starts with the provider. It creates one client, loads the session, and keeps React in step with it.
import { ZevAuthProvider } from '@zevauth/react';
<ZevAuthProvider publishableKey="pk_test_...">
<App />
</ZevAuthProvider>
useUser
const { isLoaded, isSignedIn, user } = useUser();
Three states, not two. On the first render of a page there is no answer yet. A session may be restorable from storage, and finding out takes a request.
if (!isLoaded) return <Skeleton />;
if (!isSignedIn) return <SignIn />;
return <p>Hello {user.firstName}</p>;
useAuth
The credential-shaped view: ids and a token, no profile. Use it where you only need to attach a token, so the component does not re-render every time a display name changes.
const { userId, organizationId, getToken, signOut } = useAuth();
const token = await getToken();
getToken() refreshes first if the token is close to expiring. getToken and
signOut keep a stable identity across renders, so they are safe in a
dependency array.
useOrganization and useOrganizationList
const { organization } = useOrganization();
const { organizations, setActive } = useOrganizationList();
await setActive('org_...'); // null returns to personal scope
Switching rotates the session’s tokens, because the organization is a claim inside them. See Organizations.
Members are fetched only when you ask:
const { members, isLoadingMembers } = useOrganization({ withMembers: true });
Control components
<SignedIn> …only when signed in… </SignedIn>
<SignedOut> …only when signed out… </SignedOut>
<ZevAuthLoading> …while the session resolves… </ZevAuthLoading>
And <Protect> for role and permission checks:
<Protect permission="org:members:manage" fallback={<p>Ask an admin.</p>}>
<InviteForm />
</Protect>
Errors
Anything the SDK throws is a ZevAuthError with a code you can branch on and
a message written for a person to read.
try {
await client.signIn.withPassword({ identifier, password });
} catch (err) {
if (err instanceof ZevAuthError) setError(err.message);
} Updated at, Friday, August 28, 2026