Bun Native SQL
Overview
Section titled “Overview”UQL supports Bun’s native SQL client (bun:sql) directly, so you can use Bun’s built-in drivers for PostgreSQL, MySQL, MariaDB, and SQLite with UQL’s unified API, without installing external driver packages.
Key Benefits
Section titled “Key Benefits”- Native speed: Uses Bun’s built-in SQL implementations instead of pure-JS drivers.
- Zero Dependencies: No need to install
pg,mysql2, orbetter-sqlite3. - Unified Connection: Use a single
BunSqlQuerierPoolfor all SQL dialects. - Adapter Mapping: UQL automatically configures Bun’s internal drivers to match your specified dialect, preventing silent protocol mismatches.
1. Installation
Section titled “1. Installation”You only need uql-orm. Bun provides the SQL drivers built-in.
bun add uql-orm2. Using Bun SQL
Section titled “2. Using Bun SQL”Import from uql-orm/bunSql and pass a Bun SQL.Options object (connection URL, adapter, SQLite filename, etc.). UQL infers the dialect from that shape.
import { BunSqlQuerierPool } from 'uql-orm/bunSql';import { User } from './entities.js';
// the url may be postgres://, mysql://, sqlite://, or a file path; UQL infers the dialectconst pool = new BunSqlQuerierPool({ url: 'postgres://localhost:5432/app' });
const users = await pool.findMany(User, { $limit: 10 });3. SQLite with Bun
Section titled “3. SQLite with Bun”For SQLite, use a sqlite: / file: URL, :memory:, or a filename option, whatever your Bun version accepts in SQL.Options.
const pool = new BunSqlQuerierPool({ url: 'sqlite://:memory:' });// or: new BunSqlQuerierPool({ filename: ':memory:' })4. Connection & Pooling Behaviors
Section titled “4. Connection & Pooling Behaviors”Bun’s bun:sql treats different databases with distinct connection semantics. UQL’s BunSqlQuerierPool abstracts these details so you don’t have to worry about race conditions or driver-specific errors.
Automatic Reservation (Pooling)
Section titled “Automatic Reservation (Pooling)”For PostgreSQL and MySQL, Bun exposes a .reserve() method to obtain a dedicated connection from the pool.
- UQL’s Role: UQL identifies these as “Reserved Connections.” It automatically calls
.reserve()and ensures.release()is called when the querier is released back to the pool.
Unpooled Persistence (SQLite)
Section titled “Unpooled Persistence (SQLite)”Bun’s native SQLite driver does not support connection reservation and throws if you attempt to call .reserve().
- UQL’s Role:
BunSqlQuerierPoolidentifies the SQLite dialect and transparently returns a singleton handle. It skips the reservation phase, allowing you to use the standardwithQuerierortransactionwrappers without modification.
CockroachDB
Section titled “CockroachDB”Bun talks to CockroachDB through its PostgreSQL wire adapter.
- UQL’s Role: Use a Cockroach connection URL (or
adapter: 'cockroachdb'inSQL.Optionswhen Bun exposes it). UQL keeps the dialect id ascockroachdbfor AST generation whilenormalizeBunOptsmaps Bun’sadaptertopostgresunder the hood. Since Bun’ssqlclient treats the connection exactly like Postgres at the wire level, UQL usesBunSqlCockroachDialect, the same Bun-tuned parameter binding asBunSqlPostgresDialectbelow - without it,$merge/$pushon a JSONB column would silently produce the wrong value or throw.
PostgreSQL dialect
Section titled “PostgreSQL dialect”For postgres:// / postgresql:// URLs, UQL uses BunSqlPostgresDialect, a Postgres AST tuned for Bun’s parameter binding (not the same as PgDialect for node pg). You do not configure this explicitly; the pool infers it from SQL.Options.
5. Why Bun SQL in UQL?
Section titled “5. Why Bun SQL in UQL?”Bun’s sql client has a “silent fallback” where it defaults to PostgreSQL if an adapter isn’t explicitly provided or recognized.
BunSqlQuerierPool in UQL eliminates this risk by:
- Enforcing adapter mapping: Normalizing
SQL.Optionsper dialect (e.g. CockroachDB uses Bun’spostgresadapter while UQL still emits Cockroach-specific SQL). - Dialect Guardrails: Ensuring your UQL code uses the correct SQL AST generator for the target database.
- Unified Result Mapping: Correctly handles Bun’s custom result objects, including
affectedRowsandlastInsertRowid, mapping them to UQL’s standardQueryUpdateResult.