Skip to main content

Getting started

Kysely has built-in support for PostgreSQL, MySQL and SQLite. To install it run:

# PostgreSQL
npm install kysely pg

npm install kysely mysql2

# SQLite
npm install kysely better-sqlite3

Kysely also has a simple interface for 3rd party dialects.

3rd party dialects

Minimal example

import { Pool } from 'pg'
import {
} 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
.values({ first_name: 'Jennifer', gender: 'female' })

await db
.values({ name: 'Catto', species: 'cat', owner_id: id })

const person = await db
.innerJoin('pet', 'pet.owner_id', '')
.select(['first_name', ' as pet_name'])
.where('', '=', id)

if (person) {