db0

A lightweight, unified SQL connector for Node.js with pluggable drivers for SQLite, PostgreSQL, MySQL, LibSQL, and serverless databases.

Library
npm
v0.4.1
355stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
76/100Good
Development Activity88
Maintenance76
Community60
Maturity52
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
80/100Excellent
Architecture85
Code Quality85
Innovation70
Learning Curve80

db0 is a lightweight SQL connector from the UnJS ecosystem that gives JavaScript and TypeScript projects one consistent query API across many different SQL backends. Instead of writing driver-specific code for SQLite, PostgreSQL, MySQL, LibSQL, or a serverless database like Neon, PlanetScale, or Cloudflare D1, developers create a Database instance from a chosen connector and use the same sql tagged-template and exec/prepare methods regardless of the underlying engine.

The library has zero runtime dependencies of its own — each connector dynamically and lazily imports the third-party client it wraps (better-sqlite3, pg, mysql2, @libsql/client, etc.), so consumers only install what they actually use. db0 also exposes a capabilities object per dialect (JSON support, booleans, arrays, dates, UUIDs, transactions) so calling code can branch on what a given backend actually supports, plus an opt-in tracing layer built on Node’s diagnostics_channel for query-level observability. It is designed to be embedded inside frameworks and ORMs rather than compete with them, and ships first-class integrations for Drizzle and Kysely alongside Prisma driver-adapter support.

What You Get

  • A single createDatabase(connector) API with sql tagged templates, exec, and prepare().all/run/get methods that work identically across every supported backend
  • Nine built-in connectors covering local SQLite (better-sqlite3, node:sqlite, sqlite3, bun:sqlite), PostgreSQL/MySQL, and serverless providers (Neon, PlanetScale, Cloudflare D1, Cloudflare Hyperdrive)
  • Zero runtime dependencies — each connector lazily imports its own third-party client only when actually used, and exposes a CONNECTOR_DEPENDENCIES descriptor so frameworks can check or install what’s needed
  • A capabilities object per SQL dialect describing support for JSON, booleans, arrays, dates, UUIDs, and transactions, so calling code can adapt to what the active connector supports
  • Opt-in query tracing via db0/tracing built on Node’s diagnostics_channel, emitting start/end/asyncStart/asyncEnd/error events with query text, method, connector, and result
  • Ready-made integrations for Drizzle ORM and Kysely, plus a Prisma driver adapter, so db0 can sit underneath an existing ORM instead of replacing it

Common Use Cases

  • Building a framework or meta-framework (like Nuxt or Nitro) that needs to support several SQL databases behind one internal data-access layer
  • Writing an application that must run unmodified against local SQLite in development and a serverless Postgres/MySQL provider in production
  • Adding a lightweight query layer to an edge or serverless function (Cloudflare Workers, Vercel Edge) without pulling in a full ORM
  • Instrumenting SQL query performance and errors in production using diagnostics_channel-based tracing instead of manual logging
  • Providing the underlying driver for a higher-level ORM/query-builder integration (Drizzle, Kysely, Prisma) so the ORM doesn’t need bespoke driver code per database

Under The Hood

Architecture db0’s core is small and layered: database.ts implements createDatabase(), a thin factory that wraps a supplied Connector (name, dialect, getInstance, exec, prepare, optional dispose) with disposal tracking, capability lookup, and a sql tagged-template helper that parses interpolations via template.ts (sqlTemplate) and decides whether to call .all() (for SELECT/RETURNING statements) or .run() (for everything else). Each connector under src/connectors/ (better-sqlite3, node-sqlite, sqlite3, bun-sqlite, postgresql, mysql2, libsql, neon, planetscale, cloudflare-d1, cloudflare-hyperdrive-mysql/postgresql, pglite) implements the same Connector interface independently, with shared helpers (lazyInstance, importLib, interopDefault, BoundableStatement) centralized in src/connectors/_internal/. src/_connectors.ts aggregates all connector modules and their CONNECTOR_DEPENDENCIES into typed maps consumed by index.ts. A separate src/tracing.ts wraps a Database instance with diagnostics_channel instrumentation without touching the base implementation, so tracing costs nothing when unused. This gives db0 clean separation between the stable public contract (types.ts), the dispatch logic (database.ts), and the swappable per-database implementations (connectors/*) — changing or adding a connector never touches the core.

Tech Stack db0 is written in strict TypeScript (99.9% of the codebase) targeting Node.js/Bun/Cloudflare Workers runtimes, built with obuild and distributed as ESM-only (.mjs/.d.mts) with per-connector and per-integration subpath exports (db0/connectors/*, db0/integrations/*, db0/tracing). It has no runtime dependencies itself; instead it dynamically imports whichever third-party driver a connector needs (better-sqlite3, pg, mysql2, @libsql/client, @neondatabase/serverless, @planetscale/database, @electric-sql/pglite, @cloudflare/workers-types), keeping install size minimal for consumers who use only one backend. Development tooling includes jiti for TS execution, automd for auto-generated docs/badges, changelogen for releases, and vitest for testing, all under a pnpm workspace shared with the docs/ site.

Code Quality The project has an extensive test suite under test/, including dedicated files per connector (sqlite3.test.ts, better-sqlite3.test.ts, postgresql.test.ts, postgresql-params.test.ts, mysql2.test.ts, libsql.test.ts, neon.test.ts/neon.unit.test.ts, planetscale.test.ts, pglite.test.ts, node-sqlite.test.ts, bun-test.ts) plus cross-cutting tests for capabilities, connector dependencies, the SQL template parser, and tracing. CI runs lint (Prettier), a tsc --noEmit type-check pass, Prisma client generation, vitest run --coverage, and a separate Bun test target, with coverage reported via Codecov and an autofix workflow for formatting. Naming is consistent across connectors (each exports a default factory function, ConnectorOptions, and CONNECTOR_DEPENDENCIES), and the public API is fully typed via types.ts with JSDoc comments on every exported member.

What Makes It Unique Rather than being an ORM or query builder, db0 deliberately stays a thin, dependency-free abstraction over raw SQL execution, intended to sit underneath ORMs (it ships integrations for Drizzle and Kysely and a Prisma driver adapter) rather than compete with them. Its capability-aware design — exposing per-dialect feature flags instead of pretending every backend behaves identically — combined with lazy, on-demand loading of third-party drivers and an explicit CONNECTOR_DEPENDENCIES contract, lets frameworks introspect and provision exactly what a configured connector needs without bundling every possible database client.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search