db-bridge
Unified database interface for Node.js with MySQL, PostgreSQL, Redis support and powerful migration system.
Getting Started • Documentation • Migration CLI • Contributing
Table of Contents
- Features
- Installation
- Quick Start
- Query Builder
- Migration CLI
- Transactions
- Configuration
- Documentation
- Packages
- Contributing
- License
Features
- Unified API - Same interface for MySQL, PostgreSQL, and Redis
- Query Builder - Chainable, type-safe query construction
- Migration System - Industry-grade CLI with batch tracking, rollback, checksums
- Schema Builder - Fluent API for table creation and modification
- Transactions - Full transaction support with savepoints
- Connection Pooling - Built-in connection pool management
- Seeding - Database seeding support for test data
- TypeScript - Full type safety with generics support
- ESM - Native ES modules support
- Modular - Install only the adapters you need
Installation
# All-in-one (includes all adapters)
npm install db-bridge
# Or install only what you need
npm install @db-bridge/core # Core + CLI
npm install @db-bridge/mysql # MySQL/MariaDB
npm install @db-bridge/postgresql # PostgreSQL
npm install @db-bridge/redis # Redis (cache adapter)
Quick Start
Connection
import { DBBridge } from '@db-bridge/core';
const db = DBBridge.mysql({
host: 'localhost',
user: 'root',
password: '',
database: 'myapp',
});
await db.connect();
Basic Queries
// SELECT with conditions
const users = await db
.table('users')
.select('id', 'name', 'email')
.where('status', 'active')
.orderBy('name', 'asc')
.limit(50)
.get();
// INSERT
await db.table('users').insert({
name: 'John Doe',
email: 'john@example.com',
});
// UPDATE
await db.table('users').where('id', 1).update({ status: 'inactive' });
// DELETE
await db.table('sessions').where('expires_at', '<', new Date()).delete();
Query Builder
Full-featured query builder with joins, aggregates, and more:
// JOIN
const orders = await db
.table('orders')
.join('users', 'orders.user_id = users.id')
.select('orders.*', 'users.name as customer')
.where('orders.status', 'pending')
.get();
// Complex conditions
const users = await db
.table('users')
.whereIn('role', ['admin', 'editor'])
.whereBetween('age', [18, 65])
.whereNotNull('email_verified_at')
.get();
// Aggregates
const count = await db.table('users').where('active', true).count();
const total = await db.table('orders').sum('amount');
Migration CLI
Industry-grade migration system inspired by Laravel, Knex, and Prisma.
Setup
Create db-bridge.config.mjs in your project root:
export default {
connection: {
dialect: 'mysql', // or 'postgresql'
host: 'localhost',
port: 3306,
user: 'root',
password: 'secret',
database: 'myapp',
},
migrations: {
directory: './src/migrations',
tableName: 'db_migrations', // Optional: custom table name
prefix: 'auth', // Optional: filename prefix (e.g., auth_20250119_xxx.ts)
},
seeds: {
directory: './src/seeds',
prefix: 'auth', // Optional: filename prefix (e.g., auth_users_seeder.ts)
},
};
Migration Prefix (Multi-Service Support)
The prefix option is useful for microservice architectures where multiple services share the same database. Each service can have its own migration prefix to avoid naming conflicts:
// auth-service/dbbridge.config.ts
migrations: {
directory: './src/migrations',
tableName: 'db_migrations_auth', // Separate migration tracking table
prefix: 'auth', // Creates: auth_20250119120000_create_users.ts
}
// order-service/dbbridge.config.ts
migrations: {
directory: './src/migrations',
tableName: 'db_migrations_order',
prefix: 'order', // Creates: order_20250119120000_create_orders.ts
}
Commands
# Create a new migration
npx db-bridge migrate:make create_users_table
# Run pending migrations
npx db-bridge migrate:latest
# Check migration status
npx db-bridge migrate:status
# Rollback last batch
npx db-bridge migrate:rollback
# Rollback multiple batches
npx db-bridge migrate:rollback --step=3
# Reset all migrations
npx db-bridge migrate:reset
# Fresh start (reset + migrate)
npx db-bridge migrate:fresh
# Validate migration checksums
npx db-bridge migrate:validate
# Preview migrations without executing (dry-run)
npx db-bridge migrate:latest --dry-run
# Create a seeder
npx db-bridge make:seeder users
# Run seeders
npx db-bridge db:seed
# Generate TypeScript types from database schema
npx db-bridge generate:types
# Generate types with options
npx db-bridge generate:types --output=./src/types/db.ts --camel-case
Type Generation
Generate TypeScript interfaces directly from your database schema:
npx db-bridge generate:types
This generates a file like:
// src/types/database.ts (auto-generated)
/**
* Users - users table
*/
export interface Users {
id: number;
name: string;
email: string;
password: string;
created_at: Date;
updated_at: Date | null;
}
/**
* Orders - orders table
*/
export interface Orders {
id: number;
user_id: number;
total: number;
status: string;
created_at: Date;
}
Type Generation Options
| Option | Description |
|---|---|
--output=<path> |
Output file path (default: ./src/types/database.ts) |
--tables=<list> |
Comma-separated list of tables to include |
--exclude=<list> |
Comma-separated list of tables to exclude |
--camel-case |
Use camelCase for property names |
--comments |
Include JSDoc comments (default: true) |
You can also configure type generation in your config file:
// db-bridge.config.mjs
export default {
connection: {/* ... */},
types: {
output: './src/types/database.ts',
exclude: ['logs', 'sessions'],
camelCase: true,
},
};
Seeder Ordering
Seeders support priority and dependency-based ordering to ensure data is seeded in the correct order:
// src/seeds/users_seeder.ts
import type { Seeder, DatabaseAdapter } from '@db-bridge/core';
export default {
// Lower priority runs first (default: 100)
priority: 10,
async run(adapter: DatabaseAdapter): Promise<void> {
await adapter.execute(`
INSERT INTO users (name, email) VALUES
('Admin', 'admin@example.com')
`);
},
} satisfies Seeder;
// src/seeds/orders_seeder.ts
import type { Seeder, DatabaseAdapter } from '@db-bridge/core';
export default {
// This seeder depends on users being seeded first
depends: ['users'],
async run(adapter: DatabaseAdapter): Promise<void> {
await adapter.execute(`
INSERT INTO orders (user_id, total) VALUES
(1, 99.99)
`);
},
} satisfies Seeder;
Ordering Rules:
- Seeders with dependencies run after their dependencies
- Within the same dependency level, lower priority runs first
- Default priority is 100
Migration Dry-Run
Preview SQL statements that would be executed without actually running them:
npx db-bridge migrate:latest --dry-run
Output:
ℹ Running: 20260118120000_create_users_table
ℹ DRY RUN: UP 20260118120000_create_users_table
ℹ SQL statements that would be executed:
ℹ CREATE TABLE `users` (
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(100) NOT NULL,
`email` VARCHAR(255) NOT NULL UNIQUE,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
This is useful for:
- Reviewing SQL before executing on production
- Debugging migration issues
- Generating SQL scripts for manual execution
Migration Example
// src/migrations/20260118120000_create_users_table.ts
import type { SchemaBuilder } from '@db-bridge/core';
export default {
name: '20260118120000_create_users_table',
async up(schema: SchemaBuilder): Promise<void> {
await schema.createTable('users', (table) => {
table.increments('id');
table.string('name', 100).notNull();
table.string('email', 255).unique().notNull();
table.string('password', 255).notNull();
table.boolean('active').default(true);
table.timestamps();
});
},
async down(schema: SchemaBuilder): Promise<void> {
await schema.dropTableIfExists('users');
},
};
Schema Builder API
schema.createTable('posts', (table) => {
table.increments('id'); // INT AUTO_INCREMENT PRIMARY KEY
table.bigIncrements('id'); // BIGINT AUTO_INCREMENT
table.string('title', 255); // VARCHAR(255)
table.text('content'); // TEXT
table.integer('views'); // INT
table.boolean('published'); // TINYINT(1)
table.timestamp('published_at'); // TIMESTAMP
table.json('metadata'); // JSON
table.timestamps(); // created_at, updated_at
// Foreign keys
table.integer('user_id').unsigned();
table.foreign('user_id').references('id').on('users').onDelete('CASCADE');
// Indexes
table.index('title');
table.unique('slug');
});
Transactions
await db.transaction(async (trx) => {
const orderId = await trx.table('orders').insert({
user_id: 1,
total: 99.99,
});
await trx.table('order_items').insert([
{ order_id: orderId, product_id: 1, quantity: 2 },
{ order_id: orderId, product_id: 3, quantity: 1 },
]);
await trx.table('inventory').where('product_id', 1).decrement('quantity', 2);
});
Configuration
MySQL
| Option | Type | Default | Description |
|---|---|---|---|
host |
string | localhost | Database host |
port |
number | 3306 | Database port |
user |
string | root | Username |
password |
string | - | Password |
database |
string | required | Database name |
connectionLimit |
number | 10 | Max pool connections |
PostgreSQL
| Option | Type | Default | Description |
|---|---|---|---|
host |
string | localhost | Database host |
port |
number | 5432 | Database port |
user |
string | postgres | Username |
password |
string | - | Password |
database |
string | required | Database name |
max |
number | 10 | Max pool connections |
Redis
| Option | Type | Default | Description |
|---|---|---|---|
host |
string | localhost | Redis host |
port |
number | 6379 | Redis port |
password |
string | - | Password |
db |
number | 0 | Database index |
keyPrefix |
string | - | Key prefix for all operations |
Documentation
| Guide | Description |
|---|---|
| Getting Started | Quick start guide |
| Query Builder | Full query builder API |
| Migrations | Migration system guide |
| Architecture | System architecture |
| API Reference | Complete API reference |
| Caching | Redis caching guide |
| Encryption | Field-level encryption |
| Troubleshooting | Common issues and solutions |
Packages
| Package | Description |
|---|---|
db-bridge |
All-in-one package |
@db-bridge/core |
Core interfaces, CLI, and utilities |
@db-bridge/mysql |
MySQL/MariaDB adapter |
@db-bridge/postgresql |
PostgreSQL adapter |
@db-bridge/redis |
Redis cache adapter |
Contributing
Contributions are welcome! Please read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.
# Clone the repository
git clone https://github.com/berkeerdo/db-bridge.git
# Install dependencies
npm install
# Run tests
npm test
# Build
npm run build
Requirements
- Node.js >= 18.0.0
- TypeScript >= 5.3.0 (for TypeScript users)
License
MIT berkeerdo
Made with by Berke Erdoğan