The shortest path from an empty project to one stored audit record. This walkthrough uses Bun and the built-in SQLite destination. For Node, Deno, or Workers, see Installation and the runtime guides.
Install
npm i logbunyarn add logbunpnpm add logbunbun add logbunCreate a logger
The root default is volatile in-memory reliability. Destination adapters are imported from subpaths.
import { AuditLogger } from 'logbun';
import { BunSQLiteAdapter } from 'logbun/adapters/bun-sqlite';
const audit = new AuditLogger({
namespace: 'my-app',
adapter: new BunSQLiteAdapter({ path: '.logbun/audit.db' }),
});BunSQLiteAdapter uses bun:sqlite. It only runs on Bun. On Node or Deno, supply a Turso, ClickHouse, or custom IAdapter instead.
Wait for bootstrap
await audit.ready;ready never rejects. Bootstrap failure sets audit.degraded and emits bootstrap_fail / degraded. Logs accepted before ready sit in a volatile pre-ready buffer even if you later set mode: 'durable'.
Emit an event
audit.fire('user.created', { actorId: 'u1', tenantId: 't1' });
await audit.fireAsync('user.updated', { actorId: 'u1', tenantId: 't1' });fire() never throws. fireAsync() waits until admission (journal append in durable mode) and may reject.
Flush and shut down
await audit.flush();
await audit.shutdown();flush() drains RAM queues into the destination. Request-scoped volatile hosts that need delivery before the isolate exits should await fireAsync(...); await flush().
Query the same destination:
const page = await audit.query({
tenantId: 't1',
pagination: { limit: 50 },
});
console.log(page.logs.length, page.nextCursor);Default page size is 50, clamped to [1, maxQueryLimit] (default cap 500). Rows are newest-first by UUIDv7 id.
Next
- Installation — exports, peers, runtimes
- Bun / Node / Deno / Cloudflare
- Production — replica isolation, maintenance, alerting