BunSQLiteAdapter is the only built-in destination that needs no extra package. It imports bun:sqlite and is not multi-writer HA.
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', // default
synchronous: 'FULL', // FULL | NORMAL | OFF — default FULL
busyTimeoutMs: 5_000, // default 5000
}),
});
await audit.ready;
audit.fire('user.created', { actorId: 'u1', tenantId: 't1' });
await audit.flush();
await audit.shutdown();Parent directories for path are created with dirname (Windows-safe). Journal mode is PRAGMA journal_mode = WAL. Inserts are INSERT OR IGNORE on primary key id.
Durable filesystem
import { AuditLogger, ENTERPRISE_DEFAULTS } from 'logbun';
import { BunSQLiteAdapter } from 'logbun/adapters/bun-sqlite';
import { FileReliabilityAdapter } from 'logbun/durability/filesystem';
const instanceId = Bun.env.INSTANCE_ID ?? 'my-app-instance-1';
const audit = new AuditLogger({
...ENTERPRISE_DEFAULTS,
namespace: 'my-app',
reliability: new FileReliabilityAdapter({
namespace: instanceId,
dataDir: '.logbun',
wal: { fsync: true },
dlq: { fsync: true },
}),
adapter: new BunSQLiteAdapter({ path: '.logbun/audit.db' }),
redactPaths: ['password', 'token'],
retention: { days: 90 },
});
await audit.ready;
await audit.fireAsync('course.created', {
tenantId: 'tenant_123',
actorId: 'u1',
entityId: 'course_1',
});
await audit.runMaintenance();
await audit.shutdown();LogbunConfig.namespace is validated ([a-zA-Z0-9_-]{1,64}) and is not the disk path. Replica isolation is FileReliabilityAdapter.namespace under dataDir. Use a unique reliability namespace per replica.
Do not point two processes at the same SQLite destination file as concurrent writers.