Databases
Connect to any database with Drizzle-compatible adapters.
Every database in @superapp/backend is accessed through a Drizzle-compatible adapter. The adapter architecture mirrors Drizzle ORM's driver pattern -- a core dialect layer handles SQL generation, and a thin driver adapter handles the connection.
import { createEngine } from '@superapp/backend'
const engine = createEngine({
connections: {
main: process.env.PG_URL!,
},
})How Adapters Work
Adapters follow a two-layer architecture, identical to how Drizzle ORM structures its database support:
- Core dialect -- Defines SQL generation, column types, query builders, and dialect-specific features (
pg-core,mysql-core,sqlite-core) - Driver adapter -- A thin wrapper around a specific JavaScript database driver that handles connection management, session handling, and migrations
┌─────────────────────────────────────┐
│ Your Application │
├─────────────────────────────────────┤
│ @superapp/backend engine │
├──────────┬──────────┬───────────────┤
│ pg-core │mysql-core│ sqlite-core │ ← Core dialects
├──────────┼──────────┼───────────────┤
│ pg │ mysql2 │better-sqlite3 │ ← Driver adapters
└──────────┴──────────┴───────────────┘Supported Databases
@superapp/backend supports every database that Drizzle ORM supports. Below is the full matrix organized by dialect.
PostgreSQL
| Adapter | Driver | Best for |
|---|---|---|
node-postgres | pg | Standard Node.js apps |
postgres-js | postgres | High-performance Node.js |
neon-serverless | @neondatabase/serverless | Neon (WebSocket) |
neon-http | @neondatabase/serverless | Neon (HTTP, edge/serverless) |
vercel-postgres | @vercel/postgres | Vercel managed Postgres |
supabase | @supabase/supabase-js | Supabase Postgres |
xata-http | Xata HTTP API | Xata serverless |
pglite | @electric-sql/pglite | In-browser/WASM Postgres |
aws-data-api | AWS RDS Data API | Aurora Serverless |
bun-sql | Bun.sql | Bun runtime |
MySQL
| Adapter | Driver | Best for |
|---|---|---|
mysql2 | mysql2 | Standard Node.js apps |
planetscale-serverless | @planetscale/database | PlanetScale (serverless HTTP) |
tidb-serverless | TiDB Cloud | TiDB Cloud serverless |
SQLite
| Adapter | Driver | Best for |
|---|---|---|
better-sqlite3 | better-sqlite3 | Node.js (synchronous) |
libsql | @libsql/client | Turso / LibSQL |
d1 | Cloudflare D1 | Cloudflare Workers |
durable-sqlite | Cloudflare Durable Objects | Durable Object storage |
bun-sqlite | bun:sqlite | Bun runtime |
expo-sqlite | expo-sqlite | React Native (Expo) |
op-sqlite | op-sqlite | React Native (high-performance) |
sql-js | sql.js | In-browser WASM SQLite |
SingleStore
| Adapter | Driver | Best for |
|---|---|---|
singlestore | SingleStore driver | Direct connection |
Gel (formerly EdgeDB)
| Adapter | Driver | Best for |
|---|---|---|
gel | Gel client | Gel database |
Built-in Providers
The engine ships with three built-in providers that require zero configuration beyond a connection string:
| Provider | Connection format | Read | Write | Driver |
|---|---|---|---|---|
| PostgreSQL | 'postgres://...' | Yes | Yes | pg |
| MySQL | 'mysql://...' | Yes | Yes | mysql2 |
| SQLite | './path/to/file.db' | Yes | Yes | better-sqlite3 |
| CSV | { directory: './data/' } | Yes | No | built-in |
For any other database from the supported list above, register a custom provider using the Drizzle adapter pattern.
Provider Interface
Every provider -- built-in or custom -- exports a single object that satisfies the IntegrationProvider interface:
interface IntegrationProvider {
type: string
connect: (config: ConnectionConfig) => Promise<DriverConnection>
disconnect: (connection: DriverConnection) => Promise<void>
introspect: (connection: DriverConnection) => Promise<TableSchema[]>
capabilities: {
read: boolean
write: boolean
transactions: boolean
}
}The connect method initializes the native driver connection pool. The engine calls it once on startup (or when a connection is added via the admin UI) and maintains the pool for the lifetime of the process.
Multiple Connections
Pass all connections in the connections object. The engine infers the type from the protocol or format:
const engine = createEngine({
connections: {
main: process.env.PG_URL!,
warehouse: process.env.MYSQL_URL!,
reports: { directory: './data/reports' },
},
})Next Steps
- PostgreSQL -- Full CRUD with Postgres
- MySQL -- Full CRUD with MySQL
- SQLite -- Local file-based databases
- CSV -- Read-only CSV file queries
- Custom Providers -- Build your own Drizzle-compatible provider