@krak-stack/auth
React account UI, typed Effect clients and schemas, and HttpApi middleware for integrating applications with KrakStack Auth.
@krak-stack/auth connects a TanStack Start application to KrakStack Auth across three boundaries: ready-made React account UI, typed Effect clients and schemas, and server middleware for authenticated HttpApi endpoints. The components use Better Auth underneath, share project configuration and locale through one provider, and include English and French labels.
Import the public React API from @krak-stack/auth, server-only middleware from @krak-stack/auth/server, and reusable domain schemas from @krak-stack/auth/schema.
bun add @krak-stack/auth effectComponents
Production UI for the complete account lifecycle. The forms render as focused cards; the user and organization controls render as compact dropdown triggers with full management dialogs.
Provider setup
KrakstackAuthProvider is the recommended root application boundary. It creates or accepts the Better Auth client, resolves the public project configuration, supplies the active locale, and keeps project context available to every package component. Place it once in the root document above the router content.
Components can then omit authClient and baseUrl. Use useAuthClient() for the resolved client, useKrakstackAuth() for the complete context, and useKrakstackAuthProjectConfig() for project branding and enabled authentication methods. Props still override provider values when a component needs a different client or locale.
import { KrakstackAuthProvider } from "@krak-stack/auth";
import { authClient } from "@/services/auth/client";
import { getLocale } from "@/paraglide/runtime";
export const RootDocument = ({ children }: { children: React.ReactNode }) => (
<KrakstackAuthProvider
authClient={authClient}
baseUrl={import.meta.env.VITE_KRAKSTACK_AUTH_URL}
projectId={import.meta.env.VITE_KRAKSTACK_AUTH_PROJECT_ID}
locale={getLocale()}
>
{children}
</KrakstackAuthProvider>
);Component usage
Both dropdown components support controlled dialogs, custom unauthenticated rendering, localized message overrides, and explicit client props. OrganizationSwitcher also supports locked mode for fixed-tenant applications. UserButton accepts apiKeyPermissions to constrain keys created from its dialog.
import {
MemberRequired,
OrganizationSwitcher,
Signin,
UserButton,
} from "@krak-stack/auth";
<Signin />
<OrganizationSwitcher side="right" />
<UserButton signOutRedirect="/" side="bottom" />
<MemberRequired organizationId={organizationId}>
<AdminApplication />
</MemberRequired>Effect middleware
The server export provides an AuthMiddleware for HttpApi groups secured by the x-api-key header. A successful check provides AuthService to every endpoint handler; invalid credentials become typed Unauthorized or Forbidden API errors.
For browser session-cookie APIs, create a small application middleware that builds an AuthService layer from the request headers, requires a session, and provides your own CurrentUser service. This keeps tenant scoping explicit in handlers while reusing the package's typed session client.
import { AuthMiddleware, AuthService } from "@krak-stack/auth/server";
import { Effect, Layer } from "effect";
import { HttpApiGroup } from "effect/unstable/httpapi";
export const PrivateApi = HttpApiGroup.make("private")
.add(/* endpoints */)
.middleware(AuthMiddleware);
export const AuthLive = AuthMiddleware.layer();
const handler = Effect.gen(function* () {
const auth = yield* AuthService;
const session = yield* auth.getSession();
return { userId: session.user.id };
});
export const ApiLive = PrivateApiLive.pipe(Layer.provide(AuthLive));Clients, schemas, and styling
Use AuthService for Effect programs, the exported API groups for typed HttpApi composition, and Query, Roles, or the schema subpath for shared user, organization, member, and session types. Browser components use the Better Auth client created by createAuthUiClient.
Tailwind must scan the package's distributed components. Import @krak-stack/auth/tailwind.css from the application stylesheet. Configure VITE_KRAKSTACK_AUTH_URL for browser UI and KRAKSTACK_AUTH_URL plus KRAKSTACK_AUTH_SERVICE_API_KEY for server clients.
import { AuthService } from "@krak-stack/auth";
import { Effect } from "effect";
const organizations = Effect.gen(function* () {
const auth = yield* AuthService;
return yield* auth.server.listOrganizations({
query: { userId: "user_1" },
});
}).pipe(Effect.provide(AuthService.layer()));Live component previews
These controls use this site's Better Auth client. Sign in to open their account and organization management dialogs.
Expanded
Collapsed