Getting started
Kysely has built-in support for PostgreSQL, MySQL and SQLite. To install it run:
# PostgreSQL
npm install kysely pg
# MySQL
npm install kysely mysql2
# SQLite
npm install kysely better-sqlite3
Kysely also has a simple interface for 3rd party dialects.
3rd party dialects
- PlanetScale Serverless Driver
- Cloudflare D1
- AWS RDS Data API
- SurrealDB
- Neon
- AWS S3 Select
- libSQL/sqld
- SingleStore Data API
- Postgres.js
Minimal example
import { Pool } from 'pg'
import {
Kysely,
PostgresDialect,
Generated,
ColumnType,
Selectable,
Insertable,
Updateable,
} from 'kysely'
interface PersonTable {
// Columns that are generated by the database should be marked
// using the `Generated` type. This way they are automatically
// made optional in inserts and updates.
id: Generated<number>
first_name: string
gender: 'male' | 'female' | 'other'
// If the column is nullable in the database, make its type nullable.
// Don't use optional properties. Optionality is always determined
// automatically by Kysely.
last_name: string | null
// You can specify a different type for each operation (select, insert and
// update) using the `ColumnType<SelectType, InsertType, UpdateType>`
// wrapper. Here we define a column `modified_at` that is selected as
// a `Date`, can optionally be provided as a `string` in inserts and
// can never be updated:
modified_at: ColumnType<Date, string | undefined, never>
}
interface PetTable {
id: Generated<number>
name: string
owner_id: number
species: 'dog' | 'cat'
}
interface MovieTable {
id: Generated<string>
stars: number
}
// Keys of this interface are table names.
interface Database {
person: PersonTable
pet: PetTable
movie: MovieTable
}
// You'd create one of these when you start your app.
const db = new Kysely<Database>({
// Use MysqlDialect for MySQL and SqliteDialect for SQLite.
dialect: new PostgresDialect({
pool: new Pool({
host: 'localhost',
database: 'kysely_test',
}),
}),
})
async function demo() {
const { id } = await db
.insertInto('person')
.values({ first_name: 'Jennifer', gender: 'female' })
.returning('id')
.executeTakeFirstOrThrow()
await db
.insertInto('pet')
.values({ name: 'Catto', species: 'cat', owner_id: id })
.execute()
const person = await db
.selectFrom('person')
.innerJoin('pet', 'pet.owner_id', 'person.id')
.select(['first_name', 'pet.name as pet_name'])
.where('person.id', '=', id)
.executeTakeFirst()
if (person) {
person.pet_name
}
}