Better Auth API
Generated public TypeScript reference for @relkit/better-auth.
Common APIs
For configuration and examples, read auth, better auth, sessions.
For a complete workflow, follow email password sign in.
Frontend usage
Sign in from the browser shows the client side of this capability.
Public imports
@relkit/better-auth— 7 exports@relkit/better-auth/react— 3 exports@relkit/better-auth/drizzle— 19 exports
All exported APIs
Names link to their complete contracts. Re-exports share their original contract; legacy exports keep their separate identity. Examples link to the API’s inline sample, a maintained repository usage, or the shared module walkthrough.
| API | Kind | Import from | Example |
|---|---|---|---|
| activateBetterAuthService | Value | @relkit/better-auth/drizzle |
API example |
| AuthConfiguration | Type | @relkit/better-auth/drizzle |
Source example |
| AuthFactory | Value | @relkit/better-auth/drizzle |
Source example |
| AuthFactoryInterface | Type | @relkit/better-auth/drizzle |
Module example |
| authFactoryLiveLayer | Value | @relkit/better-auth/drizzle |
API example |
| AuthFailure | Value | @relkit/better-auth/drizzle |
Source example |
| authLiveLayer | Value | @relkit/better-auth/drizzle |
Source example |
| AuthService | Value | @relkit/better-auth/drizzle |
Source example |
| AuthServiceInterface | Type | @relkit/better-auth/drizzle |
Module example |
| authServiceLayer | Value | @relkit/better-auth/drizzle |
API example |
| BETTER_AUTH_HANDLER | Value | @relkit/better-auth, @relkit/better-auth/drizzle |
Source example |
| BetterAuthActivationOptions | Type | @relkit/better-auth/drizzle |
Module example |
| BetterAuthClientLike | Type | @relkit/better-auth/react |
Module example |
| BetterAuthHandler | Type | @relkit/better-auth, @relkit/better-auth/drizzle |
Module example |
| BetterAuthRegistration | Type | @relkit/better-auth, @relkit/better-auth/drizzle |
Module example |
| BetterAuthRelkitClientProvider | Value | @relkit/better-auth/react |
API example |
| BetterAuthRelkitClientProviderProps | Type | @relkit/better-auth/react |
Module example |
| BetterAuthServiceDescriptor | Type | @relkit/better-auth, @relkit/better-auth/drizzle |
Module example |
| BetterAuthServiceOptions | Type | @relkit/better-auth |
Module example |
| BetterAuthServiceOptions | Type | @relkit/better-auth/drizzle |
Module example |
| defineBetterAuthService | Value | @relkit/better-auth, @relkit/better-auth/drizzle |
API example |
| generateBetterAuthOpenApi | Value | @relkit/better-auth/drizzle |
API example |
| InferBetterAuthSession | Type | @relkit/better-auth, @relkit/better-auth/drizzle |
Module example |
activation.ts
Binds lazy auth declarations to shared or isolated managed native owners. Failed shared acquisition is evicted; successful owners borrow the database lifecycle and preserve native settlement.
activateBetterAuthService
Binds native auth to an acquired database and its declared ALL route.
Example
import {
activateBetterAuthService,
defineBetterAuthService,
type AuthConfiguration,
} from "@relkit/better-auth/drizzle";
async function handleNativeAuth(database: AuthConfiguration["database"]): Promise<Response> {
const service = defineBetterAuthService({ baseURL: "http://localhost" });
const auth = await activateBetterAuthService(service, database, "/api/auth", { isolated: true });
return auth.handler(new Request("http://localhost/api/auth/get-session"));
}
// The application retains database ownership until admitted work completes.
Signature
declare const activateBetterAuthService: <Options extends BetterAuthServiceOptions>(
service: BetterAuthServiceDescriptor<Options>,
database: AuthDatabase,
basePath: string,
options?: BetterAuthActivationOptions,
) => Promise<Auth<any>>;
authNativeAdapter
Signature
declare const authNativeAdapter: (
owner: BetterAuthRuntime<BetterAuthServiceOptions>["activation"] & {},
native: Auth<any>,
) => Auth<any>;
runAuthPromise
Signature
declare const runAuthPromise: <A, E, R, ER>(
runtime: ManagedRuntime.ManagedRuntime<R, ER>,
effect: Effect.Effect<A, E, R>,
options?: Effect.RunOptions,
operation?: string,
) => Promise<A>;
activation.types.ts
Acquisition policy for authentication bound to an independently owned database.
BetterAuthActivationOptions (interface)
Acquisition policy for authentication bound to an independently owned database.
Signature
export interface BetterAuthActivationOptions {
/** Creates native auth without replacing the descriptor's shared handler target. */
readonly isolated?: boolean;
}
auth-database.ts
Borrows database admission and resolves its existing native declaration brand.
databaseServiceOf
Reads the established native brand; auth never acquires another database owner.
Signature
declare const databaseServiceOf: (
activation: AuthDatabase,
) => Parameters<typeof drizzleRuntimeOf>[0];
withAuthWork
Keeps SQLite serialization and owner drain admission around the complete SDK call.
Signature
declare const withAuthWork: <A, E, R>(
database: AuthDatabase,
effect: Effect.Effect<A, E, R>,
) => Effect.Effect<A, DrizzleFailure | E, R>;
auth-native-adapter.ts
Projects native SDK callables through the existing admitted auth service.
auth-run.ts
Preserves auth failures, mixed causes and native leases at the Promise boundary.
auth.errors.ts
AuthFailure (class)
Typed authentication boundary failure retaining the original SDK exception.
Signature
declare class AuthFailure
auth.factory.ts
Constructs selected native Better Auth after metadata preflight at the SDK boundary. Factory failures retain their native cause and redact secret-bearing arguments from operation telemetry.
AuthFactory (class)
Replaceable native SDK factory; auth service acquisition owns async initialization.
See
authFactoryLiveLayerfor composition with the owned auth service.
Signature
declare class AuthFactory
authFactoryLiveLayer
Production SDK construction layer; acquiring the factory does not create auth.
Example
import { Layer } from "effect";
import {
authFactoryLiveLayer,
authServiceLayer,
type AuthConfiguration,
} from "@relkit/better-auth/drizzle";
function createAuthLayer(configuration: AuthConfiguration) {
return authServiceLayer(configuration).pipe(Layer.provide(authFactoryLiveLayer));
}
Signature
declare const authFactoryLiveLayer: Layer.Layer<AuthFactory, never, never>;
makeAuthFactory
Gives substituted factory implementations the same observable operation contract.
See
authFactoryLiveLayerfor factory provisioning at service acquisition.
Signature
declare const makeAuthFactory: (create: AuthFactoryInterface["create"]) => AuthFactoryInterface;
auth.schemas.ts
AuthBasePath
Auth route prefixes exclude trailing slashes and dynamic route markers.
Signature
declare const AuthBasePath: Schema.String;
auth.service.ts
Owns admitted native authentication acquisition, handler calls and API dispatch. Database leases cover uncancellable SDK settlement; the database owner retains release authority.
AuthService (class)
Native auth service; each method admits DB work and retains SDK completion.
See
authServiceLayerfor ownership and a checked composition example.
Signature
declare class AuthService
authLiveLayer
Builds the production authentication service with the native Better Auth factory.
See
authServiceLayerfor the checked execution and ownership example.
Signature
declare const authLiveLayer: (
configuration: AuthConfiguration,
) => Layer.Layer<AuthService, AuthFailure | DrizzleFailure, never>;
authServiceLayer
Acquires authentication against a borrowed Drizzle owner using a supplied factory.
Example
import { Effect } from "effect";
import { AuthService, authLiveLayer, type AuthConfiguration } from "@relkit/better-auth/drizzle";
async function handleAuth(configuration: AuthConfiguration): Promise<Response> {
const program = Effect.flatMap(AuthService, (auth) =>
auth.handler(new Request("http://localhost/api/auth/session")),
);
return Effect.runPromise(program.pipe(Effect.provide(authLiveLayer(configuration))));
}
Signature
declare const authServiceLayer: (
configuration: AuthConfiguration,
) => Layer.Layer<AuthService, AuthFailure | DrizzleFailure, AuthFactory>;
auth.types.ts
Describes the selected Drizzle authentication bridge using actual native SDK contracts. Portable lazy declarations remain in declaration.types so backend root consumers avoid this adapter closure.
AuthConfiguration (interface)
Runtime dependencies captured once when constructing a native auth service.
Signature
export interface AuthConfiguration {
readonly options: BetterAuthServiceOptions;
readonly database: AuthDatabase;
readonly basePath: string;
}
AuthDatabase (type alias)
Borrowed database; its Drizzle owner remains solely responsible for disposal.
Signature
type AuthDatabase = DrizzleActivation<DrizzleServiceDescriptor<any, any, any, any>>;
AuthFactoryInterface (interface)
Replaceable SDK construction contract; expected SDK failures retain their cause.
Signature
export interface AuthFactoryInterface {
/**
* Constructs native auth during service acquisition.
* @param options - Native options including the owner-supplied database adapter.
* @returns Lazy factory effect retaining expected SDK failures as AuthFailure.
*/
readonly create: (options: BetterAuthOptions) => Effect.Effect<Auth<any>, AuthFailure>;
}
AuthServiceInterface (interface)
Effect-native operations sharing one native SDK instance and database admission.
Signature
export interface AuthServiceInterface {
/**
* Executes native routing while holding borrowed database admission.
* @param request - Unmodified native Request, including its cancellation signal.
* @returns Lazy response effect; SDK failures retain their original cause.
*/
readonly handler: (request: Request) => Effect.Effect<Response, AuthFailure | DrizzleFailure>;
/**
* Executes a native endpoint with its original arguments and callable metadata.
* @param method - Native API property; diagnostics normalize it to bounded labels.
* @param args - Native arguments passed without inspecting sensitive payloads.
* @returns Lazy opaque native result, with admission and SDK typed failures.
*/
readonly api: (
method: string,
args: readonly unknown[],
) => Effect.Effect<unknown, AuthFailure | DrizzleFailure>;
}
BetterAuthHandler
Signature
declare const BetterAuthHandler: BetterAuthHandler<Session>;
BetterAuthRegistration
Signature
declare const BetterAuthRegistration: BetterAuthRegistration;
BetterAuthRuntime (interface)
Server-only declaration state: the managed owner, rather than a mutable Promise.
Signature
export interface BetterAuthRuntime<Options extends BetterAuthServiceOptions> {
readonly options: Options;
activation: ManagedRuntime.ManagedRuntime<AuthService, AuthFailure | DrizzleFailure> | undefined;
handle: ((request: Request) => Promise<Response>) | undefined;
}
BetterAuthServiceDescriptor
Signature
declare const BetterAuthServiceDescriptor: BetterAuthServiceDescriptor<Options>;
BetterAuthServiceOptions (type alias)
Native options; RELKIT supplies database and the route-derived base path.
Signature
type BetterAuthServiceOptions = DeclarationOptions & {
readonly drizzle?: Omit<DrizzleAdapterConfig, "provider">;
};
InferBetterAuthSession
Signature
declare const InferBetterAuthSession: InferBetterAuthSession<Handler>;
declaration.types.ts
Lazy authentication declarations independent of a database adapter or browser.
BetterAuthDeclarationRuntime (interface)
Database-independent state populated by the explicitly selected server bridge.
Signature
export interface BetterAuthDeclarationRuntime<Options extends BetterAuthServiceOptions> {
readonly options: Options;
activation: object | undefined;
handle: ((request: Request) => Promise<Response>) | undefined;
}
BetterAuthHandler (type alias)
Native route handler retaining inferred session and user types.
Signature
type BetterAuthHandler<Session = unknown> = RawHttpHandler & {
readonly [BETTER_AUTH_HANDLER]: BetterAuthRegistration;
readonly __session?: Session;
};
BetterAuthRegistration (interface)
Frozen registration used by route discovery without acquiring native auth.
Signature
export interface BetterAuthRegistration {
readonly kind: "better-auth";
readonly service: BetterAuthServiceDescriptor<any>;
}
BetterAuthServiceDescriptor (interface)
Lazy authoring declaration whose identity survives isolated activation.
Signature
export interface BetterAuthServiceDescriptor<
Options extends BetterAuthServiceOptions,
> extends ReturnType<typeof createDescriptorBase<"service", string>> {
readonly capability: { readonly kind: "better-auth" };
readonly handler: BetterAuthHandler<Auth<Options>["$Infer"]["Session"]>;
}
BetterAuthServiceOptions (type alias)
Native options; activation supplies the database and route-derived base path.
Signature
type BetterAuthServiceOptions = Omit<BetterAuthOptions, "database" | "basePath"> & {
readonly database?: never;
readonly basePath?: never;
};
InferBetterAuthSession (type alias)
Projects the session inferred by a lazy authentication handler.
Signature
type InferBetterAuthSession<Handler> =
Handler extends BetterAuthHandler<infer Session> ? Session : never;
dependencies.ts
Checks selected native authentication requirements without evaluating the SDK.
checkNativeAuthDependencies
Resolves peers from this installed adapter, independently of the invoking CLI cache.
Signature
declare const checkNativeAuthDependencies: () => Effect.Effect<void, AuthFailure, never>;
drizzle.ts
Native Better Auth borrowing the selected Drizzle owner’s lifetime and admission.
AuthConfiguration
Signature
declare const AuthConfiguration: AuthConfiguration;
AuthFactory
Signature
declare const AuthFactory: typeof AuthFactory;
AuthFactoryInterface
Signature
declare const AuthFactoryInterface: AuthFactoryInterface;
AuthFailure
Signature
declare const AuthFailure: typeof AuthFailure;
AuthService
Signature
declare const AuthService: typeof AuthService;
AuthServiceInterface
Signature
declare const AuthServiceInterface: AuthServiceInterface;
BETTER_AUTH_HANDLER
Signature
declare const BETTER_AUTH_HANDLER: unique symbol;
BetterAuthActivationOptions
Signature
declare const BetterAuthActivationOptions: BetterAuthActivationOptions;
BetterAuthHandler
Signature
declare const BetterAuthHandler: BetterAuthHandler<Session>;
BetterAuthRegistration
Signature
declare const BetterAuthRegistration: BetterAuthRegistration;
BetterAuthServiceDescriptor
Signature
declare const BetterAuthServiceDescriptor: BetterAuthServiceDescriptor<Options>;
BetterAuthServiceOptions
Signature
declare const BetterAuthServiceOptions: BetterAuthServiceOptions;
InferBetterAuthSession
Signature
declare const InferBetterAuthSession: InferBetterAuthSession<Handler>;
activateBetterAuthService
Signature
declare const activateBetterAuthService: <Options extends BetterAuthServiceOptions>(
service: BetterAuthServiceDescriptor<Options>,
database: AuthDatabase,
basePath: string,
options?: BetterAuthActivationOptions,
) => Promise<Auth<any>>;
authFactoryLiveLayer
Signature
declare const authFactoryLiveLayer: Layer<AuthFactory, never, never>;
authLiveLayer
Signature
declare const authLiveLayer: (
configuration: AuthConfiguration,
) => Layer<AuthService, AuthFailure | DrizzleFailure, never>;
authServiceLayer
Signature
declare const authServiceLayer: (
configuration: AuthConfiguration,
) => Layer<AuthService, AuthFailure | DrizzleFailure, AuthFactory>;
defineBetterAuthService
Signature
declare const defineBetterAuthService: <const Options extends BetterAuthServiceOptions>(
options: Options,
) => BetterAuthServiceDescriptor<Options>;
Backend and frontend example
Backend — these maintained files define the operation used by the frontend below.
/** Configures email/password Better Auth against the sole database, borrowing URL and secret from server configuration. */
import { defineBetterAuthService } from "@relkit/better-auth";
export default defineBetterAuthService({
baseURL: process.env.BETTER_AUTH_URL ?? "http://127.0.0.1:3000",
// Better Auth reads BETTER_AUTH_SECRET from the server process environment.
emailAndPassword: { enabled: true },
});
/** Mounts native Better Auth once for all methods and protects the declared account, order and MCP paths. */
import { defineRoute } from "@relkit/app/routes";
import auth from "@app/services/auth/service.js";
export const ALL = defineRoute({
handler: auth.handler,
auth: { protected: ["/account/*", "/orders/*", "/mcp"] },
});
Frontend
Once the service and /api/auth mount are running, use Better Auth’s browser client for sign-in.
First complete the frontend auth installation:
import { createAuthClient } from "better-auth/client";
// Browser code: use the public backend origin, never the server secret or service.
export const authClient = createAuthClient({
baseURL: "http://127.0.0.1:3000",
basePath: "/api/auth",
fetchOptions: { credentials: "include" },
});
export async function signIn(email: string, password: string) {
const { data, error } = await authClient.signIn.email({ email, password });
if (error !== null) throw new Error(error.message ?? "Sign-in failed");
return data;
}
emailAndPassword on the service enables this signIn.email operation. Keep the public URL and
mount aligned with your backend, allow the browser to manage session cookies, and handle rejected
requests in the calling UI. These native auth endpoints are not RELKIT-generated RPC operations.
Never import the server service, database, or secret into the browser.
For application route hooks after sign-in, use
BetterAuthRelkitClientProvider as shown in
React authentication. Follow the
sign-in guide for the complete flow.
generateBetterAuthOpenApi
Signature
declare const generateBetterAuthOpenApi: (
auth: Pick<Auth, "$context">,
instrumentation?: Context<never>,
) => Promise<JsonValue>;
index.ts
Lazy authentication authoring; select /drizzle for native database activation. @packageDocumentation
defineBetterAuthService
Defines lazy authentication using the application’s Drizzle database.
Throws
TypeError When options is not an object or specifies database/basePath.
Example
import { defineBetterAuthService } from "@relkit/better-auth";
const auth = defineBetterAuthService({
baseURL: "http://127.0.0.1:3000",
emailAndPassword: { enabled: true },
});
const handler = auth.handler;
Signature
declare const defineBetterAuthService: <const Options extends BetterAuthServiceOptions>(
options: Options,
) => BetterAuthServiceDescriptor<Options>;
Since v0.0.5
Backend and frontend example
Backend — these maintained files define the operation used by the frontend below.
/** Configures email/password Better Auth against the sole database, borrowing URL and secret from server configuration. */
import { defineBetterAuthService } from "@relkit/better-auth";
export default defineBetterAuthService({
baseURL: process.env.BETTER_AUTH_URL ?? "http://127.0.0.1:3000",
// Better Auth reads BETTER_AUTH_SECRET from the server process environment.
emailAndPassword: { enabled: true },
});
/** Mounts native Better Auth once for all methods and protects the declared account, order and MCP paths. */
import { defineRoute } from "@relkit/app/routes";
import auth from "@app/services/auth/service.js";
export const ALL = defineRoute({
handler: auth.handler,
auth: { protected: ["/account/*", "/orders/*", "/mcp"] },
});
Frontend
Once the service and /api/auth mount are running, use Better Auth’s browser client for sign-in.
First complete the frontend auth installation:
import { createAuthClient } from "better-auth/client";
// Browser code: use the public backend origin, never the server secret or service.
export const authClient = createAuthClient({
baseURL: "http://127.0.0.1:3000",
basePath: "/api/auth",
fetchOptions: { credentials: "include" },
});
export async function signIn(email: string, password: string) {
const { data, error } = await authClient.signIn.email({ email, password });
if (error !== null) throw new Error(error.message ?? "Sign-in failed");
return data;
}
emailAndPassword on the service enables this signIn.email operation. Keep the public URL and
mount aligned with your backend, allow the browser to manage session cookies, and handle rejected
requests in the calling UI. These native auth endpoints are not RELKIT-generated RPC operations.
Never import the server service, database, or secret into the browser.
For application route hooks after sign-in, use
BetterAuthRelkitClientProvider as shown in
React authentication. Follow the
sign-in guide for the complete flow.
BETTER_AUTH_HANDLER
Signature
declare const BETTER_AUTH_HANDLER: unique symbol;
BetterAuthHandler
Signature
declare const BetterAuthHandler: BetterAuthHandler<Session>;
BetterAuthRegistration
Signature
declare const BetterAuthRegistration: BetterAuthRegistration;
BetterAuthServiceDescriptor
Signature
declare const BetterAuthServiceDescriptor: BetterAuthServiceDescriptor<Options>;
BetterAuthServiceOptions
Signature
declare const BetterAuthServiceOptions: BetterAuthServiceOptions;
InferBetterAuthSession
Signature
declare const InferBetterAuthSession: InferBetterAuthSession<Handler>;
openapi-projection.ts
Validates native schema JSON, prefixes mounted paths and component identities, and removes token requirements from browser-session documentation. This pure projection is called by AuthOpenApi; malformed metadata throws at that adapter.
projectAuthOpenApi
Detaches and projects one native OpenAPI document without changing SDK metadata.
Throws
TypeError When the metadata is not JSON or lacks paths.
Signature
declare const projectAuthOpenApi: <Input>(document: Input, basePath?: string) => JsonValue;
openapi.ts
Generates native authentication documentation through a typed, observable service. The activated SDK supplies endpoint metadata; projection does not acquire a database or install the plugin’s public schema/reference routes. The exported Promise function is the server compatibility boundary.
AuthOpenApi (class)
Native metadata projection with no request identity or database ownership.
Signature
declare class AuthOpenApi
generateBetterAuthOpenApi
Projects native core and plugin endpoints for RELKIT’s shared API reference.
Example
const schema = await generateBetterAuthOpenApi(auth);
Signature
declare const generateBetterAuthOpenApi: (
auth: Pick<Auth, "$context">,
instrumentation?: Context.Context<never>,
) => Promise<JsonValue>;
react.ts
BetterAuthClientLike
Signature
declare const BetterAuthClientLike: BetterAuthClientLike<Session>;
BetterAuthRelkitClientProvider
Remounts the RELKIT client whenever native authentication identity changes.
Example
import { createElement } from "react";
import { createAuthClient } from "better-auth/react";
import { BetterAuthRelkitClientProvider } from "@relkit/better-auth/react";
const authClient = createAuthClient();
const provider = createElement(BetterAuthRelkitClientProvider, { authClient, children: null });
Signature
declare const BetterAuthRelkitClientProvider: <Session>(
props: BetterAuthRelkitClientProviderProps<Session>,
) => ReactNode;
BetterAuthRelkitClientProviderProps
Signature
declare const BetterAuthRelkitClientProviderProps: BetterAuthRelkitClientProviderProps<Session>;
react.types.ts
BetterAuthClientLike (interface)
Browser SDK hook contract retaining the native inferred session type.
Signature
export interface BetterAuthClientLike<Session> {
/**
* Reads reactive authentication state; hook ownership stays with React.
* @returns Native session data, loading state and optional SDK error.
*/
useSession(): {
readonly data: Session | null | undefined;
readonly isPending: boolean;
readonly error?: unknown;
};
}
BetterAuthRelkitClientProviderProps (interface)
Client provider props with a native auth hook; no server runtime dependency.
Signature
export interface BetterAuthRelkitClientProviderProps<Session> extends RelkitClientProviderProps {
readonly authClient: BetterAuthClientLike<Session>;
}
symbols.ts
Brands a stable route handler with its owning auth declaration.
BETTER_AUTH_HANDLER
Brands a stable route handler with its owning auth declaration.
Signature
declare const BETTER_AUTH_HANDLER: unique symbol;
BETTER_AUTH_RUNTIME
Stores server-only lazy activation state without exposing it publicly.
Signature
declare const BETTER_AUTH_RUNTIME: unique symbol;