// open-source . typescript . self-hosted . MIT
TypeScript primitives for multi-tenancy, audit logging, webhooks, and email.
All running in your infrastructure, stored in your database.
import { drizzle } from "drizzle-orm/node-postgres";
import { Pool } from "pg";
import { betterAudit } from "@usebetterdev/audit";
import { drizzleAuditAdapter, withAuditProxy } from "@usebetterdev/audit/drizzle";
const db = drizzle(new Pool({ connectionString: process.env.DATABASE_URL }));
export const audit = betterAudit({
database: drizzleAuditAdapter(db),
auditTables: ["users"],
});
audit.enrich("users", "UPDATE", {
label: "user.profile.updated",
description: ({ actorId }) =>
`Actor ${actorId} updated user email and role`,
severity: "medium",
compliance: ["SOC2", "GDPR"],
redact: ["password"],
});
// use auditedDb instead of db — mutations are captured automatically
export const auditedDb = withAuditProxy(db, audit.captureLog); import { auditedDb } from "./audit";
import { usersTable } from "./schema";
import { eq } from "drizzle-orm";
// just use auditedDb like normal — audit entry captured automatically
await auditedDb.update(usersTable)
.set({ email: "new@example.com", role: "admin" })
.where(eq(usersTable.id, "usr_x9y8z7")); Composable TypeScript packages. Your server, your database, your data.
Auto-capture every ORM mutation with human-readable labels. SOC 2 and GDPR compliance-ready out of the box. Stored in your own database.
Request-scoped multi-tenancy with row-level security. Database-enforced isolation, framework adapters, CLI tooling, zero WHERE clauses.
Hosted admin dashboard that connects directly to your app. Team roles, granular permissions, magic link auth. Your data never leaves your servers.
Event registration, endpoint management, HMAC signing, reliable delivery with retries. All backed by your own database.
Transactional emails every SaaS needs — welcome flows, invites, password resets. React templates, type-safe variables, every send logged. Preview server included.
One pattern, every package. You run it. You own it.
Audit logs, webhook deliveries, email history — all in your own database. Query it, join it, export it. You own the schema forever.
Everything runs inside your Node.js process. No external API calls for core functionality. Your network perimeter, your security boundary.
TypeScript from configuration to query result. Full type inference, auto-complete, and compile-time checks across every library.
First-class adapters for Next.js, Hono, Fastify and more. Switch frameworks without rewriting a single line of business logic.
Pick a library. Follow the docs. Ship.