Multi-tenancy toolkit for Drizzle ORM
Schema isolation, tenant context propagation, and parallel migrations for PostgreSQL
| Feature | Description |
|---|---|
| Schema Isolation | PostgreSQL schema-per-tenant with automatic LRU pool management |
| Shared Schema | Full support for shared schema migrations and seeding (plans, roles, permissions) |
| Parallel Migrations | Apply migrations to all tenants concurrently with progress tracking |
| Cross-Schema Queries | Type-safe joins between tenant and shared tables |
| Schema Linting | Validate schemas with 8 configurable rules (naming, conventions, security) |
| Scaffolding | Generate schemas, seeds, and migrations from templates |
| Export/Import | Export to JSON Schema, TypeScript types, or Mermaid ERD diagrams |
| Observability | Built-in Prometheus exporter with Express/Fastify integrations |
| Framework Support | First-class Express, Fastify, and NestJS integrations |
npm install drizzle-multitenant drizzle-orm pg// tenant.config.ts
import { defineConfig } from 'drizzle-multitenant';
import * as tenantSchema from './schemas/tenant';
export default defineConfig({
connection: { url: process.env.DATABASE_URL! },
isolation: {
strategy: 'schema',
schemaNameTemplate: (id) => `tenant_${id}`,
},
schemas: { tenant: tenantSchema },
});// app.ts
import { createTenantManager } from 'drizzle-multitenant';
import config from './tenant.config';
const tenants = createTenantManager(config);
// Type-safe database for each tenant
const db = tenants.getDb('acme');
const users = await db.select().from(schema.users);# Setup & Migrations
npx drizzle-multitenant init --template=full # Enhanced setup wizard
npx drizzle-multitenant generate --name=users # Generate tenant migration
npx drizzle-multitenant generate:shared --name=plans # Generate shared migration
npx drizzle-multitenant migrate --all # Apply to all tenants
npx drizzle-multitenant migrate:shared # Apply shared migrations
# Developer Tools
npx drizzle-multitenant scaffold:schema orders # Generate schema file
npx drizzle-multitenant lint # Validate schemas
npx drizzle-multitenant doctor # Diagnose configuration
npx drizzle-multitenant export --format=mermaid # Export ERD diagram
# Tenant Management
npx drizzle-multitenant status # Check migration status
npx drizzle-multitenant tenant:create --id=acme # Create new tenant
npx drizzle-multitenant seed:all # Seed shared + tenantsExpress
import { createExpressMiddleware } from 'drizzle-multitenant/express';
app.use(createExpressMiddleware({
manager: tenants,
extractTenantId: (req) => req.headers['x-tenant-id'] as string,
}));
app.get('/users', async (req, res) => {
const db = req.tenantContext.db;
const users = await db.select().from(schema.users);
res.json(users);
});Fastify
import { fastifyTenantPlugin } from 'drizzle-multitenant/fastify';
fastify.register(fastifyTenantPlugin, {
manager: tenants,
extractTenantId: (req) => req.headers['x-tenant-id'] as string,
});
fastify.get('/users', async (req, reply) => {
const db = req.tenantContext.db;
const users = await db.select().from(schema.users);
return users;
});NestJS
import { TenantModule, InjectTenantDb } from 'drizzle-multitenant/nestjs';
@Module({
imports: [
TenantModule.forRoot({
config,
extractTenantId: (req) => req.headers['x-tenant-id'],
}),
],
})
export class AppModule {}
@Injectable({ scope: Scope.REQUEST })
export class UserService {
constructor(@InjectTenantDb() private db: TenantDb) {}
findAll() {
return this.db.select().from(users);
}
}| Getting Started | Configuration | CLI Commands |
| Shared Schema | Scaffolding | Schema Linting |
| Export & Import | Cross-Schema Queries | Advanced Features |
| Express | Fastify | NestJS |
- Node.js 18+
- PostgreSQL 12+
- Drizzle ORM 0.29+
MIT