Skip to content

What is Better Tenant?

Better Tenant is an open-source library that adds multi-tenancy to your Postgres application in minutes. Instead of manually adding WHERE tenant_id = ? to every query, Better Tenant uses Postgres Row-Level Security (RLS) to enforce tenant boundaries at the database level.

Key features

  • Database-enforced isolation — RLS policies ensure tenants can never access each other’s data, even if your application code has a bug.
  • Zero WHERE clauses — queries are automatically scoped to the current tenant. Write db.select().from(projects) and only that tenant’s projects come back.
  • Request-scoped context — tenant identity is resolved from incoming requests (header, subdomain, path, JWT, or custom) and propagated via AsyncLocalStorage.
  • Framework adapters — drop-in middleware for Hono, Express, and Next.js App Router.
  • ORM adapters — first-class support for Drizzle ORM and Prisma, with transaction-scoped tenant context.
  • CLI tooling — generate migrations, verify your RLS setup, and seed tenants from the command line.
  • Admin operationsrunAs and runAsSystem for background jobs, cron tasks, and cross-tenant admin work.

How it works

  1. A request arrives with a tenant identifier (header, subdomain, path, JWT, or custom function).
  2. Middleware resolves the identifier to a tenant UUID.
  3. The adapter opens a database transaction and runs SELECT set_config('app.current_tenant', '<uuid>', true) — the function form of SET LOCAL.
  4. Your handler executes — every query is automatically filtered by RLS to the current tenant.
  5. The transaction commits and the session variable is cleared (safe for connection pooling).

Because the tenant context is transaction-scoped (SET LOCAL), it works safely with connection pools like pg.Pool — no cross-request leakage.

Architecture

Better Tenant follows a layered architecture:

LayerPackageRole
Core@usebetterdev/tenant-coreContext, resolver, adapter contract, API. Zero runtime dependencies.
ORM adapterstenant-drizzle, tenant-prismaTransaction wrapping, SET LOCAL, RLS bypass.
Framework adapterstenant-hono, tenant-express, tenant-nextMiddleware that resolves tenant and delegates to the adapter.
CLI@usebetterdev/tenant-cliMigrations, verification, seeding.
Umbrella@usebetterdev/tenantSingle install, subpath exports for everything.

You install the umbrella package (@usebetterdev/tenant) and import adapters via subpath exports like @usebetterdev/tenant/drizzle and @usebetterdev/tenant/hono.

Next steps

  • Installation — install the package and its peer dependencies
  • Quick Start — get a working multi-tenant app in 5 minutes