Features / Database Adapters

Database Adapters.

PostgreSQL, MySQL, and SQLite, all powered by Drizzle ORM. Pick the database that fits your project and switch adapters without changing application code.

Nextly uses a database adapter pattern that abstracts the database layer behind a common interface. All three adapters extend a shared DrizzleAdapter base class from @nextlyhq/adapter-drizzle, which provides CRUD operations, query building, and transaction management through Drizzle ORM.

Each adapter handles database-specific details: PostgreSQL uses the pg driver with connection pooling and supports JSONB, arrays, and full-text search. MySQL uses mysql2 with connection pooling and workarounds for the missing RETURNING clause. SQLite uses better-sqlite3 with synchronous operations wrapped for async compatibility, WAL mode, and RETURNING clause support (SQLite 3.35+).

You choose your database with two environment variables and Nextly handles the rest: schema creation, migrations, and runtime query execution all go through the adapter it builds on boot.

Key capabilities

  • Three Databases. PostgreSQL for production with JSONB, arrays, and full-text search. MySQL for full feature sets. SQLite for development and testing.
  • Drizzle ORM. All adapters extend a shared DrizzleAdapter base class. Type-safe queries, schema management, and relational access via the Drizzle instance.
  • Connection Pooling. PostgreSQL and MySQL adapters include connection pooling with configurable min/max connections, idle timeouts, and connection timeouts.
  • Transaction Support. Full ACID transactions with configurable isolation levels. Automatic retry for serialization failures and deadlocks.

Capabilities by database

  • JSONB. PostgreSQL: yes; MySQL: JSON only; SQLite: JSON only
  • Array types. PostgreSQL: yes; MySQL: no; SQLite: no
  • Full-text search. PostgreSQL: yes; MySQL: FULLTEXT; SQLite: FTS5
  • RETURNING clause. PostgreSQL: yes; MySQL: no; SQLite: yes (3.35+)
  • Connection pooling. PostgreSQL: pg.Pool; MySQL: mysql2; SQLite: N/A (single file)
  • Savepoints. PostgreSQL: yes; MySQL: disabled; SQLite: yes
  • ON CONFLICT / upsert. PostgreSQL: yes; MySQL: DUPLICATE KEY; SQLite: yes
  • Auto retry. PostgreSQL: serialization + deadlock; MySQL: deadlock; SQLite: no
  • Best for. PostgreSQL: production; MySQL: production; SQLite: development / testing

One package per database

  • PostgreSQL (@nextlyhq/adapter-postgres, driver: pg / node-postgres). Full features: JSONB, arrays, full-text search, RETURNING, savepoints, connection pooling.
  • MySQL (@nextlyhq/adapter-mysql, driver: mysql2). Full feature set with workarounds for missing RETURNING clause. Connection pooling and deadlock retry.
  • SQLite (@nextlyhq/adapter-sqlite, driver: better-sqlite3). File-based or in-memory. WAL mode for concurrency. RETURNING clause support (3.35+). Great for development.

Database adapter configuration

Nextly picks the adapter from your environment. Install the package for your
database and set two variables; the runtime instantiates the adapter on boot.

PostgreSQL

pnpm add @nextlyhq/adapter-postgres pg
DB_DIALECT=postgresql
DATABASE_URL=postgresql://user:password@localhost:5432/mydb

For SSL on a managed provider such as Neon, Supabase or RDS, append
?sslmode=require to the URL, or set PGSSLMODE=require.

MySQL

pnpm add @nextlyhq/adapter-mysql mysql2
DB_DIALECT=mysql
DATABASE_URL=mysql://user:password@localhost:3306/mydb

SQLite

pnpm add @nextlyhq/adapter-sqlite better-sqlite3
DB_DIALECT=sqlite
DATABASE_URL=file:./data/nextly.db

The path can be relative, resolved against the project root, or absolute. The
directory has to exist.

Constructing an adapter yourself

Only for a custom bootstrap, such as a test harness or a script. The runtime
does this for you.

import { createPostgresAdapter } from "@nextlyhq/adapter-postgres";

const adapter = createPostgresAdapter({
  url: process.env.DATABASE_URL!,
});

await adapter.connect();

Start building with Nextly

Free, open source, and yours to own. No sign-up required.

Terminal