Last Updated: 3/20/2026
Installation
Kysely requires two packages: the core kysely library and a dialect driver for your database. The dialect driver is a third-party library (like pg for PostgreSQL or mysql2 for MySQL) that Kysely uses to communicate with your database.
Prerequisites
Before installing Kysely, ensure you have:
- TypeScript 4.6 or later (5.4+ recommended for improved type inference, 5.9+ for faster compilation)
- Node.js 20.0.0 or later (if running in Node.js)
- Strict mode enabled in your
tsconfig.json:
{
"compilerOptions": {
"strict": true
}
}Kysely’s type safety depends on TypeScript’s strict mode. Without it, many type errors will go undetected.
Core Installation
Install Kysely using your preferred package manager:
# npm
npm install kysely
# yarn
yarn add kysely
# pnpm
pnpm add kyselyThis installs the core query builder. Next, install a dialect driver for your database.
PostgreSQL
For PostgreSQL, install the pg driver:
npm install pg
npm install --save-dev @types/pgThe pg package is the official PostgreSQL client for Node.js. The @types/pg package provides TypeScript definitions.
Minimal working example:
import { Kysely, PostgresDialect } from 'kysely'
import { Pool } from 'pg'
interface Database {
person: {
id: number
name: string
}
}
const db = new Kysely<Database>({
dialect: new PostgresDialect({
pool: new Pool({
host: 'localhost',
database: 'my_database',
user: 'postgres',
password: 'password',
port: 5432,
})
})
})The PostgresDialect class (see src/dialect/postgres/postgres-dialect.ts) wraps the pg connection pool and handles PostgreSQL-specific SQL generation. The pool option can also be a function that returns a Pool instance, allowing lazy initialization:
new PostgresDialect({
pool: async () => new Pool({ /* config */ })
})MySQL
For MySQL or MariaDB, install the mysql2 driver:
npm install mysql2The mysql2 package is a fast MySQL client with promise support and better performance than the older mysql package.
Minimal working example:
import { Kysely, MysqlDialect } from 'kysely'
import { createPool } from 'mysql2'
interface Database {
person: {
id: number
name: string
}
}
const db = new Kysely<Database>({
dialect: new MysqlDialect({
pool: createPool({
host: 'localhost',
database: 'my_database',
user: 'root',
password: 'password',
port: 3306,
})
})
})The MysqlDialect class (see src/dialect/mysql/mysql-dialect.ts) wraps the mysql2 connection pool. Like PostgreSQL, the pool option can be a function for lazy initialization.
Microsoft SQL Server
For MS SQL Server, install both tedious (the driver) and tarn (a connection pool library):
npm install tedious tarn
npm install --save-dev @types/tedious @types/tarnMS SQL Server requires more configuration than other databases because tedious doesn’t include a built-in connection pool. Kysely uses tarn to manage pooling.
Minimal working example:
import { Kysely, MssqlDialect } from 'kysely'
import * as Tedious from 'tedious'
import * as Tarn from 'tarn'
interface Database {
person: {
id: number
name: string
}
}
const db = new Kysely<Database>({
dialect: new MssqlDialect({
tarn: {
...Tarn,
options: {
min: 0,
max: 10,
},
},
tedious: {
...Tedious,
connectionFactory: () => new Tedious.Connection({
authentication: {
options: {
userName: 'sa',
password: 'YourPassword',
},
type: 'default',
},
options: {
database: 'my_database',
port: 1433,
trustServerCertificate: true,
},
server: 'localhost',
}),
},
})
})The MssqlDialect class (see src/dialect/mssql/mssql-dialect.ts) requires both tarn and tedious configuration. The connectionFactory function creates new tedious connections, and tarn pools them.
SQLite
For SQLite, install the better-sqlite3 driver:
npm install better-sqlite3
npm install --save-dev @types/better-sqlite3The better-sqlite3 package is a synchronous SQLite client with excellent performance. Kysely wraps its synchronous API to provide a consistent async interface.
Minimal working example:
import { Kysely, SqliteDialect } from 'kysely'
import Database from 'better-sqlite3'
interface DatabaseSchema {
person: {
id: number
name: string
}
}
const db = new Kysely<DatabaseSchema>({
dialect: new SqliteDialect({
database: new Database('my_database.db')
})
})The SqliteDialect class (see src/dialect/sqlite/sqlite-dialect.ts) wraps the better-sqlite3 database instance. For in-memory databases, use new Database(':memory:'). Like other dialects, the database option can be a function for lazy initialization.
Verifying Installation
After installation, verify everything works by running a simple query:
const result = await db.selectFrom('person').selectAll().execute()
console.log(result)If you see a connection error, check your database credentials and ensure the database server is running. If you see a TypeScript error about missing columns, verify your Database interface matches your actual database schema.
What’s Next
- Defining Database Types: Learn how to define the TypeScript interface that maps your database schema, including column types, nullable fields, and generated columns.
- First Query: Write your first SELECT query and see how Kysely enforces type safety at every step.