Introducing FlexiDB - The Ultimate Multi-Database Solution for Prisma Developers

Discover FlexiDB, a lightweight and type-safe abstraction layer for managing multiple independent databases in a single Node.js application. With seamless Prisma integration, dynamic runtime registration, and built-in health checks, FlexiDB is the perfect tool for multi-tenant architectures and microservices.

Introducing FlexiDB - The Ultimate Multi-Database Solution for Prisma Developers
M
Muhammad Surya

Overview

Managing multiple databases in a single Node.js application can be challenging, especially when using Prisma, which traditionally supports only one database per schema. This limitation often forces developers to merge schemas, manually manage client lifecycles, or deal with complex workarounds.

Enter FlexiDB—a lightweight, type-safe abstraction layer on top of Prisma v6 and v7+ that simplifies multi-database management. With FlexiDB, you can seamlessly register, access, and manage multiple independent databases without merging schemas, restarting your server, or writing boilerplate code.

In this article, we’ll explore what makes FlexiDB stand out, its key features, and how you can integrate it into your projects today.


Why Choose FlexiDB?

FlexiDB addresses the limitations of Prisma by providing a clean and developer-friendly solution for managing multiple databases. Here’s why FlexiDB is a game-changer:

1. No Schema Merge

With FlexiDB, each database has its own .prisma file, eliminating the need to merge schemas into a single schema.prisma. This keeps your project organized and maintainable.

2. Dynamic Registration

Need to add or remove databases at runtime? FlexiDB allows you to dynamically register and unregister databases without restarting your application—a must-have for multi-tenant architectures.

3. Built-In Health Checks

FlexiDB provides db.health() and db.stats() methods to monitor the status of all registered databases, ensuring your application stays resilient.

4. Connection Retry

Automatic reconnection with exponential backoff ensures your application remains robust even in unstable network conditions.

5. Event Hooks

FlexiDB supports lifecycle hooks like onConnect, onDisconnect, onError, and onRetry, giving you full control over database events.

6. CLI Tooling

The flexidb CLI simplifies tasks like generating Prisma clients, running migrations, and scaffolding new projects across multiple schemas.


Key Features

Here’s a closer look at some of FlexiDB’s standout 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 & 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 with ease:

# 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

Setting up FlexiDB is straightforward. Follow these steps to get started:

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

FlexiDB excels in multi-tenant architectures. Dynamically register tenant databases at runtime:

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 is a powerful yet lightweight solution for managing multiple databases in a single Node.js application. Its seamless integration with Prisma, dynamic runtime registration, and built-in health checks make it an invaluable tool for modern applications, especially in multi-tenant and microservice environments.

Whether you’re building a SaaS platform, integrating legacy systems, or working with data lakes, FlexiDB simplifies the complexity of multi-database management while maintaining full TypeScript support and type safety.

Give FlexiDB a try today and experience the joy of effortless multi-database management!

For more details, check out the official documentation.


License: ISC Built with ❤️ in Indonesia. Open source. Zero magic. Just TypeScript.