Quickstart
From zero to a signed-in user.
Signet speaks the better-auth wire, so there is no Signet SDK to learn. Install the stock better-auth client, point its baseURL at your instance’s /api/auth, and the calls you already write just work. Five frameworks, one copy-paste path each.
import { createAuthClient } from "better-auth/client";
// Your existing better-auth client — point baseURL
// at your Signet instance. The wire is the contract.
export const authClient = createAuthClient({
baseURL: "https://auth.example.com/api/auth",
});
// The same calls you already write — they just work.
await authClient.signIn.email({ email, password });The shape
Three constants, every framework.
Whatever you build with, the path is the same three moves. The frameworks below differ only in where they hold state.
- Install the stock client —
bun add better-auth(ornpm i better-auth). No Signet package. - Point
baseURLat your instance’s/api/auth. The wire is the contract, and it reads the same hosted or on-prem. - Call the methods you already know —
signUp.email,signIn.email,useSession,getSession,signOut.
Quickstart I
Next.js — App Router
The React client (better-auth/react) gives you signIn.email and the useSession hook inside your "use client" components.
Install the stock client — bun add better-auth. It speaks the certified better-auth wire, so there is nothing Signet-specific to add.
import { createAuthClient } from "better-auth/react";
// One client for the whole app — the stock better-auth
// React client, pointed at your Signet instance.
export const authClient = createAuthClient({
baseURL: "https://auth.example.com/api/auth",
});
// In a "use client" component: sign in, then read the
// session with the hook. Same calls you already write.
await authClient.signIn.email({ email, password });
const { data, isPending } = authClient.useSession();To read the session in a Server Component or Route Handler, forward the request cookies with the vanilla better-auth/client — the same pattern as Quickstart IV.
Quickstart II
React — single-page app
A pure browser app talks to your instance directly. The React client (better-auth/react) carries signUp.email, useSession, and signOut — no backend of your own required.
Install the stock client — bun add better-auth. It speaks the certified better-auth wire, so there is nothing Signet-specific to add.
import { createAuthClient } from "better-auth/react";
export const authClient = createAuthClient({
baseURL: "https://auth.example.com/api/auth",
});
// Create an account (swap for signIn.email to log in).
await authClient.signUp.email({ email, password, name });
// Read the session with the hook; sign out when done.
const { data, isPending } = authClient.useSession();
await authClient.signOut();Everything runs in the browser against your instance. Hosted or on-prem, this client does not change — the wire is the contract.
Quickstart III
React Router v7
There is no React-Router-specific better-auth package, and none is needed: use the React client in components, and the vanilla client inside a server loader to read the session with the incoming request headers.
Install the stock client — bun add better-auth. It speaks the certified better-auth wire, so there is nothing Signet-specific to add.
// app/lib/auth-client.ts — the React client for components.
import { createAuthClient } from "better-auth/react";
export const authClient = createAuthClient({ baseURL: "https://auth.example.com/api/auth" });
await authClient.signIn.email({ email, password });
// app/routes/dashboard.tsx — read the session in a loader by
// forwarding the request cookies to your Signet instance.
export async function loader({ request }) {
const session = await authClient.getSession({
fetchOptions: { headers: request.headers },
});
if (!session.data) throw redirect("/login");
return { user: session.data.user };
}Gate any route by redirecting when session.data is null; the loader runs on the server, so the check never reaches the browser.
Quickstart IV
Node / Express — session verification
Your backend becomes a resource server. The vanilla better-auth/client forwards the caller’s session cookie to Signet and reads session.data.user — Signet holds the credentials, your API just checks the session.
Install the stock client — npm i better-auth. It speaks the certified better-auth wire, so there is nothing Signet-specific to add.
import express from "express";
import { createAuthClient } from "better-auth/client";
const authClient = createAuthClient({
baseURL: "https://auth.example.com/api/auth",
});
// Verify the caller's session against Signet on each request.
async function requireUser(req, res, next) {
const session = await authClient.getSession({
fetchOptions: { headers: { cookie: req.headers.cookie ?? "" } },
});
if (!session.data) return res.status(401).json({ error: "not signed in" });
req.user = session.data.user;
next();
}Attach requireUser to any route that needs a signed-in caller; a missing or expired session returns 401 without your backend ever storing a password.
Quickstart V
Plain JavaScript — no framework
The vanilla client (better-auth/client) is the one every other quickstart builds on: createAuthClient, signIn.email, getSession, signOut. It runs in any JavaScript runtime.
Install the stock client — bun add better-auth. It speaks the certified better-auth wire, so there is nothing Signet-specific to add.
import { createAuthClient } from "better-auth/client";
const authClient = createAuthClient({
baseURL: "https://auth.example.com/api/auth",
});
// Every call returns { data, error } — it does not throw.
const { data, error } = await authClient.signIn.email({ email, password });
// Read the current session; sign out to end it.
const session = await authClient.getSession();
await authClient.signOut();This is the whole integration surface. Any framework is this client plus that framework’s own way of holding state — there is nothing Signet-specific to learn.
better-auth/client for server-side session reads. Every method shown traces to better-auth 1.6.23, the release Signet is certified against (compatibility gap 0 — scoped to what better-auth's own suite exercises here, not a claim that every better-auth route is implemented; the full statement is on /compatibility).The wire is the same at 2am.
Every deployed instance serves its own /docs and certification receipt from inside the binary — the reference never drifts from the build you run. Get an instance and point your client at it.