Skip to main content
Kysely’s primary goal is to provide end-to-end type safety for SQL queries. Every column reference, table name, and return type is validated at compile time.

Database Type Parameter

Type safety starts with the database type parameter passed to Kysely<DB>:
This single type parameter powers all type inference throughout Kysely.

Column Selection Type Inference

Kysely infers the return type based on selected columns:

Aliased Columns

SelectAll

Table Reference Validation

Only tables defined in the database interface can be referenced:

Column Reference Validation

Columns must exist in the selected table(s):

JOIN Type Safety

After a join, columns from both tables are available:

Join Reference Validation

WHERE Clause Type Safety

WHERE clauses are validated against available columns and their types:

INSERT Type Safety

Inserted values must match the table’s Insertable type:

UPDATE Type Safety

Updated values must match the table’s Updateable type:

Return Type Inference

Return types change based on execution method:

Expression Builder Type Safety

The expression builder provides type-safe access to columns in callbacks:
The eb parameter knows which columns are available in the current context:

Type Narrowing with Generics

Kysely’s query builders are generic, allowing for composable, type-safe functions:

Dynamic Table Access

For runtime-dynamic table access, use db.dynamic.ref():
Using db.dynamic bypasses Kysely’s type safety. Only use it when absolutely necessary.

Compile-Time vs Runtime

Kysely provides compile-time type safety. Type information is erased at runtime:
Use database migration tools and testing to ensure your TypeScript types match your actual database schema.

Best Practices

Keep your database interface in sync with your actual database schema using migrations or code generation tools.
Use Selectable, Insertable, and Updateable type helpers to extract operation-specific types from your table interfaces.
Avoid using any or type assertions. If you need dynamic queries, use db.dynamic sparingly and document why it’s necessary.
Kysely’s type safety is structural, not nominal. Two tables with identical column types are considered compatible.