kysely-postgres-js offers a Kysely dialect for PostgreSQL that supports the Postgres.js client library (version >= 3.4) and Bun's (version >= 1.2) SQL native binding.
This dialect should not be confused with Kysely's core PostgreSQL dialect, which supports the significantly more adopted pg client library and Neon's WebSockets Pool instead. Both of these dialects are maintained by members of the Kysely core team and are production ready.
npm install kysely-postgres-js postgres kyselypnpm add kysely-postgres-js postgres kyselyyarn add kysely-postgres-js postgres kyselydeno add npm:kysely-postgres-js npm:postgres npm:kyselybun add kysely-postgres-js kyselyimport { type GeneratedAlways, Kysely } from 'kysely'
import { PostgresJSDialect } from 'kysely-postgres-js'
import postgres from 'postgres'
interface Database {
person: {
id: GeneratedAlways<number>
first_name: string | null
last_name: string | null
age: number
}
}
const db = new Kysely<Database>({
dialect: new PostgresJSDialect({
postgres: postgres({
database: 'test',
host: 'localhost',
max: 10,
port: 5434,
user: 'admin',
}),
}),
})
const people = await db.selectFrom("person").selectAll().execute();import { SQL } from 'bun'
import { type GeneratedAlways, Kysely } from 'kysely'
import { PostgresJSDialect } from 'kysely-postgres-js'
interface Database {
person: {
id: GeneratedAlways<number>
first_name: string | null
last_name: string | null
age: number
}
}
const db = new Kysely<Database>({
dialect: new PostgresJSDialect({
postgres: new SQL({
database: 'test',
host: 'localhost',
max: 10,
port: 5434,
user: 'admin',
}),
}),
})
const people = await db.selectFrom("person").selectAll().execute();This dialect supports Kysely's AbortSignal integration, including the
'cancel query' and 'kill session' values of inflightQueryAbortStrategy,
which stop the aborted query on the database side:
await db
.selectFrom('person')
.selectAll()
.execute({
signal: AbortSignal.timeout(5_000),
inflightQueryAbortStrategy: 'kill session',
})Under the hood, 'cancel query' uses Postgres.js'
native wire-protocol cancellation when running on Postgres.js,
and pg_cancel_backend on a control connection when running on Bun's
SQL (whose cancel() doesn't cancel queries on
the database side). 'kill session' executes pg_terminate_backend on a
control connection in both cases.
By default, control queries (e.g. pg_terminate_backend) are executed on a
connection acquired from the postgres pool. This might mean waiting for an
idle connection, and with a small, saturated pool (e.g. max: 1), it can wait
forever - the aborted query's connection is only returned to the pool after
the control query runs.
To avoid this, provide controlPostgres. You can pass postgres or Bun's
SQL directly - it is invoked with the main instance's resolved options, with
max overridden to 1. A custom factory receiving those options works too.
Both libraries' pools are lazy, so the control instance doesn't hold a
connection until the first control query runs.
import { Kysely } from 'kysely'
import { PostgresJSDialect } from 'kysely-postgres-js'
import postgres from 'postgres'
const db = new Kysely<Database>({
dialect: new PostgresJSDialect({
controlPostgres: postgres,
postgres: postgres({
database: 'test',
host: 'localhost',
max: 10,
port: 5434,
user: 'admin',
}),
}),
})import { SQL } from 'bun'
import { Kysely } from 'kysely'
import { PostgresJSDialect } from 'kysely-postgres-js'
const db = new Kysely<Database>({
dialect: new PostgresJSDialect({
controlPostgres: SQL,
postgres: new SQL({
database: 'test',
host: 'localhost',
max: 10,
port: 5434,
user: 'admin',
}),
}),
})