# Hono Integration (/docs/integrations/hono)

Integrate Better Auth with Hono.



Both Hono and Better Auth use the Web Standard `Request` and `Response` APIs, so you can mount Better Auth directly in a Hono application without an adapter.

Before you begin, make sure you have a Better Auth instance configured. If not, follow the [installation guide](/docs/installation).

## Setup [#setup]

### Create a Hono App [#create-a-hono-app]

If you are starting a new project, create a Hono application and select the template for your runtime or platform:

<CodeBlockTabs defaultValue="npm" groupId="persist-install">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="npm">
      npm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="pnpm">
      pnpm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="yarn">
      yarn
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="bun">
      bun
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="npm">
    ```bash
    npx create-hono@latest
    ```
  </CodeBlockTab>

  <CodeBlockTab value="pnpm">
    ```bash
    pnpm dlx create-hono@latest
    ```
  </CodeBlockTab>

  <CodeBlockTab value="yarn">
    ```bash
    yarn dlx create-hono@latest
    ```
  </CodeBlockTab>

  <CodeBlockTab value="bun">
    ```bash
    bun x create-hono@latest
    ```
  </CodeBlockTab>
</CodeBlockTabs>

If you already have a Hono application, you can skip this step. See the [create-hono documentation](https://hono.dev/docs/guides/create-hono) for available templates and options, or Hono's [Getting Started guides](https://hono.dev/docs/getting-started/basic) for runtime-specific setup and deployment.

### Mount the Auth Handler [#mount-the-auth-handler]

Add the highlighted route to your existing Hono application:

```ts title="src/index.ts"
import { Hono } from "hono";
import { auth } from "./auth";

const app = new Hono();

app.all("/api/auth/*", (c) => auth.handler(c.req.raw)); // [!code highlight]

export default app;
```

That's all you need to connect Better Auth to Hono!

If you're using another runtime, keep your existing entry point and add the same `app.all()` route.

`app.all()` forwards every HTTP method to Better Auth using the raw Web Standard `Request` from `c.req.raw`. Better Auth validates the method and returns a `Response` that Hono sends directly. Register the auth route before any catch-all route that could handle the request first.

<Callout type="info">
  The resulting Hono route must match your Better Auth `basePath`, which
  defaults to `/api/auth`. If your app already uses `new
          Hono().basePath("/api")`, mount Better Auth at `/auth/*`:

  ```ts
  const app = new Hono().basePath("/api");

  app.all("/auth/*", (c) => auth.handler(c.req.raw));
  ```
</Callout>

### Additional Configuration [#additional-configuration]

#### Cloudflare Workers [#cloudflare-workers]

Better Auth uses `AsyncLocalStorage`. Add the [`nodejs_compat` compatibility flag](https://developers.cloudflare.com/workers/configuration/compatibility-flags/#nodejs-compatibility-flag) to your Wrangler configuration:

```jsonc title="wrangler.jsonc"
{
  // Use "nodejs_als" instead if you only need AsyncLocalStorage.
  "compatibility_flags": ["nodejs_compat"],
}
```

## CORS [#cors]

To allow cross-origin authentication requests, register Hono's [CORS middleware](https://hono.dev/docs/middleware/builtin/cors) before the Better Auth route:

```ts title="src/index.ts"
import { Hono } from "hono";
import { cors } from "hono/cors"; // [!code highlight]
import { auth } from "./auth";

const app = new Hono();

app.use( // [!code highlight]
	"/api/auth/*", // [!code highlight]
	cors({ // [!code highlight]
		origin: "http://localhost:3001", // [!code highlight]
		credentials: true, // [!code highlight]
	}), // [!code highlight]
); // [!code highlight]

app.all("/api/auth/*", (c) => auth.handler(c.req.raw));

export default app;
```

Add the same origin to Better Auth's `trustedOrigins` configuration:

```ts title="auth.ts"
import { betterAuth } from "better-auth";

export const auth = betterAuth({
	trustedOrigins: ["http://localhost:3001"], // [!code highlight]
});
```

When `credentials` is enabled, configure an explicit CORS origin instead of `*` and add the same origin to Better Auth's `trustedOrigins`. See [Cookies](/docs/concepts/cookies) for cross-domain and cross-subdomain cookie behavior.

## Middleware [#middleware]

You can also use custom middleware to make the current session available through Hono's context:

```ts title="src/session-middleware.ts"
import { createMiddleware } from "hono/factory";
import { auth } from "./auth";

type Env = {
	Variables: {
		session: typeof auth.$Infer.Session | null;
	};
};

export const sessionMiddleware = createMiddleware<Env>(async (c, next) => {
	const session = await auth.api.getSession({
		headers: c.req.raw.headers,
	});

	c.set("session", session);

	await next();
});
```

Add the middleware to any route that needs access to the current session:

```ts title="src/index.ts"
import { Hono } from "hono";
import { HTTPException } from "hono/http-exception";
import { sessionMiddleware } from "./session-middleware";

const app = new Hono();

app.get("/hello", sessionMiddleware, (c) => {
	const session = c.get("session");

	if (!session) {
		throw new HTTPException(401);
	}

	return c.json({ message: `Hello, ${session.user.name}.` });
});

export default app;
```

This example applies the middleware to a single route. For other patterns, see Hono's [Middleware guide](https://hono.dev/docs/guides/middleware).

## Hono RPC [#hono-rpc]

The Better Auth client uses `credentials: "include"` by default. If you use Hono RPC to call authenticated Hono routes from another origin, configure the RPC client to include credentials as well:

<Tabs items="[&#x22;Client&#x22;, &#x22;Server&#x22;]">
  <Tab value="Client">
    ```ts title="src/client.ts"
    import { hc } from "hono/client";
    import type { AppType } from "./server";

    const client = hc<AppType>("http://localhost:8787", {
        init: { // [!code highlight]
            credentials: "include", // [!code highlight]
        }, // [!code highlight]
    });

    const response = await client.hello.$get();
    ```
  </Tab>

  <Tab value="Server">
    ```ts title="src/server.ts"
    import { Hono } from "hono";

    // Assume this route requires an authenticated session. // [!code highlight]
    const app = new Hono().get("/hello", (c) => {
        return c.json({ message: "Hello!" });
    });

    export type AppType = typeof app;
    export default app;
    ```
  </Tab>
</Tabs>

This configuration is only required for cross-origin requests. For more information, see Hono's [RPC cookies guide](https://hono.dev/docs/guides/rpc#cookies).

