SDKs
@au1h/client
Browser SDK, a Better Auth client bound to your application plus JWT and gateway helpers.
npm i @au1h/client better-authTwo entry points with the same API: @au1h/client (framework-agnostic) and
@au1h/client/react (adds useSession and the other React hooks).
Create a client
import { createAu1hClient } from "@au1h/client/react";
import { organizationClient } from "better-auth/client/plugins"; // optional
export const auth = createAu1hClient({
baseURL: "https://auth.example.com",
appSlug: "todo",
plugins: [organizationClient()], // any Better Auth client plugins
});| Option | Default | Notes |
|---|---|---|
baseURL | required | au1h URL, no trailing slash |
appSlug | required | Sent as x-app-id on every request |
plugins | [] | Better Auth client plugins |
tokenStorage | localStorage keyed by slug, or memory | Where the JWT is kept between loads |
refreshLeewaySeconds | 60 | Refresh the JWT this long before expiry |
Authentication
Everything Better Auth's client offers, with the app header already set:
await auth.signUp.email({ email, password, name });
await auth.signIn.email({ email, password });
await auth.signIn.social({ provider: "github", callbackURL: "/dashboard" });
const { data: session } = await auth.getSession();
await auth.signOut(); // also clears the cached JWTfunction Profile() {
const { data, isPending } = auth.useSession();
if (isPending) return null;
return data ? <p>{data.user.email}</p> : <SignIn />;
}Passwordless and email flows
The magic-link and one-time-code plugins are enabled by default. Links in the emails land on pages your app hosts; see Email.
await auth.signIn.magicLink({ email, callbackURL: "/" });
await auth.emailOtp.sendVerificationOtp({ email, type: "sign-in" });
await auth.signIn.emailOtp({ email, otp });
await auth.requestPasswordReset({ email, redirectTo: "/reset-password" });
await auth.resetPassword({ newPassword, token }); // token from the landing page URL
await auth.sendVerificationEmail({ email, callbackURL: "/welcome" });Tokens and fetch helpers
const token = await auth.getToken(); // valid JWT; cached, refreshed before expiry
const claims = auth.getClaims(); // decoded (not verified) cached claims, or null
// Call your own backend with Authorization: Bearer <jwt>
const res = await auth.authFetch("https://api.todo.example.com/me");
// Call through the au1h gateway (session cookie + x-app-id)
const todos = await auth.proxyFetch("/todos");getToken throws Au1hError with status: 401 when there is no session.
Without the Better Auth client
The helpers are available on their own:
import { createTokenManager } from "@au1h/client";
const tokens = createTokenManager({ baseURL, appSlug: "todo" });
await tokens.getToken();