dbSDK

Universal database layer for stores you don't own

TypeScript SDK for databases whose schema you don't control. Providers for the product, drivers for the database type — query-only, safe for generated reads.

$ npm install @db-sdk/core
db.ts
import { connect } from "@db-sdk/core";
import { postgres } from "@db-sdk/postgres";

const db = await connect({
  provider: postgres({
    connectionString: process.env.DATABASE_URL,
  }),
});

await db.test();
console.log({
  id: db.id,
  driver: db.driver,
  capability: db.capability,
});

2.4M

Weekly downloads

3.1K

GitHub stars

84+

Contributors

12+

Providers

Providers and drivers, one lifecycle

Open-source TypeScript toolkit for customer databases and AI-generated reads. Hosted providers (Supabase) open a shared driver (Postgres). Same verbs everywhere — not one query language for every store.

  • Runtime schema

    The catalog is discovered after connect — not generated from a schema file you wrote.

  • Native queries

    Postgres speaks SQL. Firestore does not. DB SDK does not translate one language into another.

  • Query-only

    query() is a bounded read. Writes, migrations, and LLM calls stay out of the SDK.

postgres.ts
import { connect } from "@db-sdk/core";
import { postgres } from "@db-sdk/postgres";

const db = await connect({
  provider: postgres({
    connectionString: process.env.DATABASE_URL,
  }),
});

await db.test();
const catalog = await db.introspect();
const users = await db.query({
  sql: "SELECT id, email FROM users WHERE plan = $1",
  params: ["pro"],
});

Security

Treat generated queries as untrusted. SDK validation is extra — the real lock is a read-only database user.

Full security model

SDK

extra

Read-oriented API, default time and row limits. Fail closed when unsure. Not a security boundary.

$ await db.query()

Provider

extra

Engine-specific checks. SQL policy on the Postgres driver. Read APIs only on Firestore. Not a security boundary.

$ npm i @db-sdk/postgres

Runtime

extra

Timeouts, required or injected limits, abort signals, and bounded result payloads.

$ AbortSignal.timeout()

Database

the lock

The lock: a dedicated read-only role or IAM principal, restricted schemas, TLS.

$ GRANT SELECT

Build with DB SDK today

Get started from the intended API. Packages are documentation-first until the first release. Browse all resources

$ npm install @db-sdk/core

Customer databases

Attach to each customer's Postgres, Firestore, or other store at runtime. Discover the schema after they connect.

customer.ts
const db = await connect({
  provider: registry.resolve(
    customer.provider,
    customer.credentials,
  ),
});

await db.test();
return db.introspect();

Cross-driver tools

Investigation consoles work across drivers. Adding a store should mean adding a provider, not rewriting the host.

tools.ts
const dbA = await connect({ provider: providerA(optsA) });
const dbB = await connect({ provider: providerB(optsB) });

const [left, right] = await Promise.all([
  dbA.introspect(),
  dbB.introspect(),
]);

AI-generated queries

The app owns the model and the API key. DB SDK takes the catalog out, treats the query as untrusted input, and runs a bounded read.

agent.ts
const catalog = await db.introspect();
const sql = await model.generateQuery(catalog, prompt);

const result = await db.query({ sql, params });
// generated SQL is untrusted input