Authentication for the Scratchy framework, powered by
Better Auth. Provides a server-side auth factory,
a Fastify plugin that resolves sessions on every request, typed
request.session / request.user decorators, and preHandler hooks for
protecting routes.
pnpm add @scratchyjs/auth// src/auth.ts
import { createAuth } from "@scratchyjs/auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
export const auth = createAuth({
secret: process.env.BETTER_AUTH_SECRET,
trustedOrigins: ["http://localhost:3000"],
emailAndPassword: { enabled: true },
database: drizzleAdapter(db, { provider: "pg" }),
});Register after the database plugin so fastify.db is available.
import { auth } from "./auth.js";
import authPlugin from "@scratchyjs/auth/plugin";
await server.register(authPlugin, { auth });
// Every request now has:
// request.session — AuthSession | null
// request.user — AuthUser | nullimport { requireAdmin, requireAuth } from "@scratchyjs/auth/hooks";
// Authenticated users only (HTTP 401 otherwise)
fastify.get("/profile", { preHandler: requireAuth }, (request) => {
return request.user;
});
// Admin users only (HTTP 401 / 403 otherwise)
fastify.delete("/users/:id", { preHandler: requireAdmin }, async (request) => {
const { id } = request.params as { id: string };
await deleteUser(id);
return { success: true };
});import { createAuthClient } from "@scratchyjs/auth/client";
const authClient = createAuthClient({ baseURL: "/api/auth" });
await authClient.signIn.email({ email, password });
await authClient.signOut();
const session = await authClient.getSession();Thin wrapper around betterAuth(). Accepts any valid
Better Auth options. Returns an
AuthInstance.
Creates a browser-side Better Auth client. options.baseURL should point to
your auth endpoint (default /api/auth).
Registers
fastify-better-auth
and adds an onRequest hook that resolves the session and sets
request.session (AuthSession | null) and request.user (AuthUser | null).
Options
| Option | Type | Description |
|---|---|---|
auth |
AuthInstance |
The instance returned by createAuth(). |
Fastify preHandler hook. Sends HTTP 401 when request.session is null.
Fastify preHandler hook. Sends HTTP 401 when unauthenticated; HTTP 403 when
request.session.user.role !== "admin".
Once the plugin is registered, Better Auth mounts these routes under
/api/auth:
| Method | Path | Description |
|---|---|---|
| POST | /api/auth/sign-up/email |
Register a new user |
| POST | /api/auth/sign-in/email |
Sign in with email/password |
| POST | /api/auth/sign-out |
Sign out |
| GET | /api/auth/get-session |
Get current session |
| POST | /api/auth/forgot-password |
Request password reset |
| POST | /api/auth/reset-password |
Reset password |