Database Drivers
Overview of available database drivers for VibORM
VibORM supports multiple database drivers across three dialects: PostgreSQL, MySQL, and SQLite.
PostgreSQL Drivers
| Driver | Package | Best For |
|---|---|---|
| pg | pg |
Traditional Node.js apps with connection pooling |
| postgres | postgres |
Modern apps using postgres.js |
| pglite | @electric-sql/pglite |
Local/embedded PostgreSQL (WASM) |
| neon-http | @neondatabase/serverless |
Serverless/edge deployments |
| bun-sql | bun:sql |
Bun runtime applications |
MySQL Drivers
| Driver | Package | Best For |
|---|---|---|
| mysql2 | mysql2 |
Traditional Node.js MySQL apps |
| planetscale | @planetscale/database |
PlanetScale serverless MySQL |
SQLite Drivers
| Driver | Package | Best For |
|---|---|---|
| sqlite3 | better-sqlite3 |
Node.js apps with local SQLite |
| libsql | @libsql/client |
Turso cloud or local libSQL |
| bun-sqlite | bun:sqlite |
Bun runtime with SQLite |
| d1 | Cloudflare Workers | Cloudflare D1 in Workers |
Feature Matrix
| Driver | Dynamic Transactions | Batch Mode | Migration Atomicity | Environment |
|---|---|---|---|---|
| pg | ✅ Full | ✅ Full | ✅ Full | Node.js |
| postgres | ✅ Full | ✅ Full | ✅ Full | Node.js |
| pglite | ✅ Full | ✅ Full | ✅ Full | Any (WASM) |
| neon-http | ❌ Unsupported | ✅ Full | ⚠️ Push only; migrate apply rejects |
Any |
| bun-sql | ✅ Full | ✅ Full | ✅ Full | Bun |
| mysql2 | ✅ Full | ✅ Full | ⚠️ DDL-limited | Node.js |
| planetscale | ✅ Single-shard atomic | ✅ Single-shard atomic | ⚠️ DDL-limited | Any |
| sqlite3 | ✅ Full | ✅ Full | ✅ Full | Node.js |
| libsql | ✅ Full | ✅ Full | ✅ Full | Any |
| bun-sqlite | ✅ Full | ✅ Full | ✅ Full | Bun |
| d1 | ❌ Unsupported | ✅ Full | ⚠️ Push only; migrate apply rejects |
Workers |
Closing the Connection
await client.$disconnect() closes the client’s driver. Where the platform has
the explicit-resource-management protocol, await using does the same thing at
the end of the block — including when the block is left by a throw:
await using client = createClient({ driver, schema });
const users = await client.user.findMany();
// leaving this block closes `driver`, thrown or not
Disposal and $disconnect() are the same close path, so combining them in
either order closes once and throws nothing. Drivers are disposable too
(await using driver = new PgDriver({ ... })).
The interactive transaction client is deliberately not disposable: inside
$transaction(async (tx) => ...), the transaction owns its driver’s lifetime,
and a using block that tried to close it would be fighting the transaction.
Choosing a Driver
- Node.js traditional: Use
pg,mysql2, orsqlite3 - Serverless/Edge: Use
neon-http,planetscale,libsql, ord1 - Bun runtime: Use
bun-sqlorbun-sqlite - Cloudflare D1: Use
d1with a Workers binding; itsbatch()primitive is the supported atomic path - Local development: Use
pglite,sqlite3, orbun-sqlite