> ## Documentation Index
> Fetch the complete documentation index at: https://docs.theauth.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Waku

> Serve theAuth routes from a Waku API route with `createTheAuthHandler`. No extra package, plus the bundler settings Waku needs for native packages.

Waku API routes export functions named after HTTP methods. Each takes a Web `Request` and returns a `Response`, which is what `createTheAuthHandler` from `@glinr/theauth/http` produces. There is no Waku package.

API routes live in `src/pages/_api`. The `_api` directory is not part of the URL, so `src/pages/_api/theauth/[...path].ts` answers at `/theauth/*`.

## Install

```bash theme={"dark"}
pnpm add @glinr/theauth better-sqlite3 waku react react-dom react-server-dom-webpack
```

## Create the instance once

```typescript title="src/lib/theauth.ts" theme={"dark"}
import { createTheAuth } from "@glinr/theauth";
import { createTheAuthHandler } from "@glinr/theauth/http";

async function setup() {
  const theauth = await createTheAuth({
    database: { provider: "sqlite-native", url: "theauth.db" },
    agents: { enabled: true, maxPerUser: 10, defaultPermissions: [], auditAll: true },
  });
  const handler = createTheAuthHandler(theauth, {
    basePath: "/theauth",
    // Who may call the management routes. Return { id } to allow, null for a 401.
    authenticate: async (request) => {
      const user = await theauth.auth.resolveUser(request);
      return user ? { id: user.id } : null;
    },
  });
  return { theauth, handler };
}

let instance: ReturnType<typeof setup> | undefined;

export function useTheAuth() {
  instance ??= setup();
  return instance;
}
```

## Mount the handler

```typescript title="src/pages/_api/theauth/[...path].ts" theme={"dark"}
import { useTheAuth } from "../../../lib/theauth";

const serve = async (request: Request): Promise<Response> => {
  const { handler } = await useTheAuth();
  return handler(request);
};

export const GET = serve;
export const POST = serve;
export const PUT = serve;
export const PATCH = serve;
export const DELETE = serve;
```

API routes are dynamic by default, so no `getConfig` is needed.

## Keep native packages out of the bundle

Waku builds with Vite and Rolldown and bundles server dependencies. Two things then break: `better-sqlite3` fails with `__dirname is not defined` on the first request, and `@glinr/theauth` carries an optional `nodemailer` import that Rolldown refuses to leave unresolved. Mark both external:

```typescript title="waku.config.ts" theme={"dark"}
import { defineConfig } from "waku/config";

export default defineConfig({
  vite: {
    build: {
      rolldownOptions: {
        // Native and optional packages stay in node_modules instead of being bundled.
        external: ["better-sqlite3", "nodemailer"],
      },
    },
  },
});
```

If you use the email adapters or another optional driver, add its package name to `external` the same way. With Postgres you would externalize `pg` instead of `better-sqlite3`.

## Protect your own routes

```typescript title="src/pages/_api/docs.ts" theme={"dark"}
import { requireAgent } from "@glinr/theauth/http";
import { useTheAuth } from "../../lib/theauth";

export const GET = async (request: Request): Promise<Response> => {
  const { theauth } = await useTheAuth();
  const result = await requireAgent(theauth, request, { action: "read", resource: "docs" });
  if (!result.ok) return result.response; // 401 or 403 with { error: { code, message } }
  return Response.json({ agentId: result.agent.id });
};
```

## What was run

A scratch Waku project (`waku@1.0.0-rc.3`, React 19.3, Node 22) with `@glinr/theauth` installed from a packed tarball. After `waku build` and `waku start`: `GET /theauth/agents` without a session answered 401, an unknown path under the mount answered 404, and `GET /docs` without a token answered 401. Both failures described above were reproduced before the config was added. The session cookie flow for pages (server components reading the session) was not run.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.