Article
Introducing FlexiDB - A Multi-Database Solution for Prisma Developers
FlexiDB is a lightweight, type-safe abstraction layer for managing multiple independent databases in one Node.js app, with Prisma integration, dynamic runtime registration, and built-in health checks.
Overview
Managing multiple databases in a single Node.js application gets messy fast, especially with Prisma, which traditionally supports only one database per schema. That limitation usually pushes developers toward merging schemas, hand-rolling client lifecycle management, or other workarounds nobody enjoys.
I built FlexiDB to get rid of that pain: a lightweight, type-safe abstraction layer on top of Prisma v6 and v7+ for managing multiple databases. With FlexiDB, you can register, access, and manage several independent databases without merging schemas, restarting your server, or writing the boilerplate you’d otherwise need.
Why FlexiDB
1. No schema merging
Each database gets its own .prisma file, so you never have to cram everything into a single schema.prisma. Your project stays organized as it grows.
2. Dynamic registration
Need to add or remove a database while the app is running? FlexiDB lets you register and unregister databases at runtime, which matters a lot if you’re building multi-tenant architecture.
3. Built-in health checks
db.health() and db.stats() give you the connection status of every registered database so you can catch problems before they take down a request.
4. Connection retry
If the network drops, FlexiDB reconnects automatically with exponential backoff instead of leaving you with a dead client.
5. Event hooks
Lifecycle hooks like onConnect, onDisconnect, onError, and onRetry give you a place to react to what’s happening to each connection.
6. CLI tooling
The flexidb CLI handles the repetitive parts: generating Prisma clients, running migrations, and scaffolding new projects across multiple schemas.
Key features
Multi-database support
Register as many databases as you need, each with its own .prisma file and Prisma client.
const db = createFlexiDB({
user: new UserPrismaClient({ adapter: userAdapter }),
analytics: new AnalyticsPrismaClient({ adapter: analyticsAdapter }),
}); Dynamic runtime registration
Add or remove databases dynamically at runtime using db.register() and db.unregister().
db.register('tenant_acme', new TenantClient({ adapter: acmeAdapter }));
await db.unregister('tenant_acme'); Health checks and statistics
Monitor database connectivity and performance with db.health() and db.stats().
const status = await db.health();
// { user: true, analytics: false }
const stats = db.stats();
// { user: { connected: true, lastError: null }, analytics: { connected: false, lastError: Error } } Auto-generated code
The npx flexidb codegen command reads your schemas and generates a ready-to-use db.ts file with all imports and configurations.
npx flexidb codegen CLI commands
Run Prisma commands across all schemas at once:
# Generate Prisma clients for all schemas
npx flexidb generate
# Apply migrations to all databases
npx flexidb migrate deploy
# Open Prisma Studio for a specific schema
npx flexidb studio --schema user Getting started with FlexiDB
Step 1: Install dependencies
npm install flexidb prisma @prisma/client
# or
yarn add flexidb prisma @prisma/client Step 2: Scaffold your project (optional)
If you’re starting from scratch, run:
npx flexidb init This creates a prisma/schemas/ directory, an example schema, and a .env.example file.
Step 3: Define your schemas
Create separate .prisma files for each database under prisma/schemas/.
// prisma/schemas/user.prisma
generator client {
provider = "prisma-client"
output = "../../src/generated/user"
}
datasource db {
provider = "mysql"
}
model User {
id Int @id @default(autoincrement())
email String @unique
createdAt DateTime @default(now())
} Step 4: Generate Prisma clients
npx flexidb generate This generates Prisma clients for all schemas in prisma/schemas/.
Step 5: Auto-generate your db.ts
npx flexidb codegen This creates a src/db.ts file with all imports and configurations wired up.
import { createFlexiDB } from 'flexidb';
import { PrismaClient as UserPrismaClient } from './generated/user/client';
import { PrismaClient as AnalyticsPrismaClient } from './generated/analytics/client';
export const db = createFlexiDB({
user: new UserPrismaClient({ adapter: userAdapter }),
analytics: new AnalyticsPrismaClient({ adapter: analyticsAdapter }),
}); Step 6: Use it anywhere
import { db } from './db';
// Query user database
const users = await db.get('user').user.findMany();
// Query analytics database
const events = await db.get('analytics').event.findMany(); Connecting to databases
FlexiDB supports both Prisma v6 (URL-based) and Prisma v7+ (adapter-based) connections.
Prisma v7+ (adapter-based)
Install the adapter for your database:
npm install @prisma/adapter-mysql mysql2 Configure the adapter:
import { PrismaMysql } from '@prisma/adapter-mysql';
import { createPool } from 'mysql2';
const userAdapter = new PrismaMysql(
createPool({ uri: process.env.DATABASE_URL_USER })
);
export const db = createFlexiDB({
user: new UserPrismaClient({ adapter: userAdapter }),
}); Prisma v6 (URL-based)
Pass the connection URL directly:
export const db = createFlexiDB({
user: new UserPrismaClient({
datasourceUrl: process.env.DATABASE_URL_USER,
}),
}); Multi-tenancy example
This is where FlexiDB earns its keep. You can register tenant databases dynamically, as they’re created:
import { createFlexiDB } from 'flexidb';
import { PrismaClient as TenantClient } from './generated/tenant/client';
import { PrismaMysql } from '@prisma/adapter-mysql';
import { createPool } from 'mysql2';
export const db = createFlexiDB({
core: new CorePrismaClient({ adapter: coreAdapter }),
});
export async function onTenantCreated(tenantId: string, dbUrl: string) {
const adapter = new PrismaMysql(createPool({ uri: dbUrl }));
db.register(tenantId, new TenantClient({ adapter }));
}
export async function onTenantDeleted(tenantId: string) {
await db.unregister(tenantId);
} Conclusion
FlexiDB solves a specific, annoying problem: managing multiple databases in one Node.js app without fighting Prisma’s single-schema assumption. Between the Prisma integration, dynamic runtime registration, and built-in health checks, it holds up well in multi-tenant setups and microservices where you’re juggling more than one connection.
If you’re building a SaaS platform, stitching together legacy systems, or working across data lakes, FlexiDB keeps the multi-database plumbing out of your way while keeping full TypeScript support and type safety.
Source and docs are on GitHub.
License: ISC Built in Indonesia. Open source. No hidden magic, just TypeScript.