ORM adapters
Two thin packages wrap @persql/sdk so you can plug PerSQL into the
Drizzle or Kysely query builders without writing the proxy yourself.
Drizzle
Section titled “Drizzle”npm i @persql/sdk @persql/drizzle drizzle-ormimport { drizzle } from "@persql/drizzle";import { PerSQL } from "@persql/sdk";import { eq } from "drizzle-orm";import * as schema from "./schema";
const persql = new PerSQL({ token: process.env.PERSQL_TOKEN! });const db = drizzle(persql.database("acme/orders"), { schema });
const users = await db .select() .from(schema.users) .where(eq(schema.users.id, 42));Generate schema.ts from a live database:
npx persql-codegen --token $PERSQL_TOKEN \ --database acme/orders > schema.tsThe wrapper plugs into Drizzle’s sqlite-proxy driver, so every
Drizzle feature — query builder, prepared statements, transactions,
relations — works without modification.
Kysely
Section titled “Kysely”npm i @persql/sdk @persql/kysely kyselyimport { Kysely } from "kysely";import { PerSQLDialect } from "@persql/kysely";import { PerSQL } from "@persql/sdk";
interface DB { users: { id: number; email: string }; orders: { id: number; user_id: number; total: number };}
const persql = new PerSQL({ token: process.env.PERSQL_TOKEN! });const db = new Kysely<DB>({ dialect: new PerSQLDialect({ database: persql.database("acme/orders") }),});
const rows = await db .selectFrom("users") .innerJoin("orders", "orders.user_id", "users.id") .select(["users.email", "orders.total"]) .execute();Kysely’s db.transaction() is implemented natively: statements
between BEGIN and COMMIT are buffered and shipped as one
transactional batch, so a transaction is one HTTP round-trip.
Why ship adapters at all?
Section titled “Why ship adapters at all?”The SDK already exposes db.driver() (the Drizzle proxy callback) so
you could wire either ORM by hand. The packages just save a few
imports and document the integration as an officially-supported
surface.