---
title: "Hono"
description: "Attach auditLog.fire / fireAsync to the Hono context with trusted XFF and optional tenant resolution."
---

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

# Hono

```sh
npm install hono
pnpm add hono
yarn add hono
bun add hono
```

```ts
import { Hono } from 'hono';
import { AuditLogger } from 'logbun';
import {
  createAuditMiddleware,
  type LogbunHonoVariables,
} from 'logbun/plugins/hono';
import type { IAdapter } from 'logbun';

type Actions = 'course.created';

declare const adapter: IAdapter;
declare function tenantIdFromVerifiedSession(c: unknown): string | undefined;

const audit = new AuditLogger<Actions>({
  namespace: 'api',
  adapter,
  requireTenantId: true,
});
await audit.ready;

const app = new Hono<{ Variables: LogbunHonoVariables<Actions> }>();
app.use(
  '*',
  createAuditMiddleware(audit, {
trustedProxyCount: 1,
getTenantId: (c) => tenantIdFromVerifiedSession(c),
  }),
);

app.post('/courses', async (c) => {
  const auditLog = c.get('auditLog');
  auditLog.fire('course.created', { actorId: 'user_1', entityId: 'course_1' });
  await auditLog.fireAsync('course.created', {
actorId: 'user_1',
entityId: 'course_1',
  });
  return c.json({ ok: true });
});
```

`auditLog.fire` never throws. `auditLog.fireAsync` may reject.

Hono does not take `getWaitUntil`. The middleware reads `c.executionCtx.waitUntil` structurally when present (Workers) and wraps it so host throws cannot escape `fire()`.

Options:

```ts
{
  trustedProxyCount?: number; // default 0
  getTenantId?: (c: Context) => string | undefined;
}
```

IP trust is documented on [Plugins](/reference/plugins).

Source: https://logbun-docs.abshahin.workers.dev/guides/hono/index.mdx
