# Kysely: a type-safe TypeScript SQL query builder, not an ORM

> Kysely compiles your SQL through TypeScript's type system so that table and column names are checked before the query runs. It is a query builder for people who want SQL, not a model layer.

**kysely-org/kysely** — A type-safe TypeScript SQL query builder. Mainly developed for Node.js but also runs on all other JavaScript environments like Deno, Bun, Cloudflare Workers and web browsers.

- Repository: https://github.com/kysely-org/kysely
- Website: https://kysely.dev
- Stars: 14,243 · Forks: 446
- Language: TypeScript
- License: MIT
- Published: 2026-08-04 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/kysely-org-kysely

## What Kysely solves, and who it is actually for

Raw SQL in TypeScript has a specific failure mode: the string is opaque to the compiler. Rename a column, and nothing complains until a query runs in production. Kysely's answer is to move table and column references into TypeScript types, so that, as the README puts it, the library "makes sure you only refer to tables and columns that are visible to the part of the query you're writing." The result type carries only the selected columns, with their types and aliases.

The intended audience is teams that already think in SQL. If your mental model is SELECT with joins and CTEs, Kysely keeps that model and adds checking on top. If your mental model is objects with relations, you will be writing more code than you expect. The README states the project was "inspired by Knex.js" and is "mainly developed for Node.js but also runs on all other JavaScript environments like Deno, Bun, Cloudflare Workers and web browsers." That portability is a design constraint, not a marketing line: the package has no Node-only dependency in its main export, and the exports map lists separate helper entry points for mssql, mysql, postgres and sqlite.

## How the type inference works across joins, aliases and subqueries

The mechanism is compile-time parsing of the query builder chain. Each method returns a new builder type that accumulates what the query has seen so far. When you select pet.name with an alias, the README says Kysely can "parse the alias given to pet.name and add the pet_name column to the result row type." The same inference extends to selected subqueries, joined subqueries and with statements.

This is why the API documentation lives in the typing files. The README says "All API documentation is written in the typing files and you can simply hover over the module, class or method you're using to see it in your IDE." There is a hosted copy at kysely-org.github.io/kysely-apidoc, but the practical workflow is editor-driven.

The escape hatches matter as much as the inference. The README is explicit that "there are cases where things cannot be typed at compile time," and points to the sql template tag and the DynamicModule. Those are the places where you trade type safety for reach, and the type system will not stop you from writing a wrong column name inside a raw sql fragment.

## Getting started: where Kysely says to install it

The README does not include install steps. It sends readers to the documentation site at kysely.dev for getting started, with per-dialect links for postgresql, mysql, mssql, sqlite and pglite. The same README badges the npm package and jsr.io/@kysely/kysely, so both registries are published targets.

What the repository files do confirm is the runtime floor. package.json declares "name": "kysely" and an engines field of node >=22.0.0, so a project on an older Node release cannot install the current package.

The exports map is the part worth reading before you write an import. It lists the root entry plus separate subpaths: ./helpers/mssql, ./helpers/mysql, ./helpers/postgres, ./helpers/sqlite, ./migration and ./readonly. That means dialect helpers and the migration module are imported from their own paths rather than the package root, and a bundler will only pull in the helper you name.

For a first real use, the shape of the work is this. You describe your tables as a TypeScript interface, create a Kysely instance with a dialect, and then write queries against that interface. The compiler checks the query against your description. It does not check against the live database, so the interface is the contract, and keeping it accurate is your responsibility. Generating it from a running database is a separate tool; the README's credits list Robin Blomberg for kysely-codegen, which is what the codegen search phrase refers to.

The repository's own docker-compose.yml shows which engines the test suite exercises and on which host ports: mssql on 21433, mysql on 3308, and postgres on 5434. Those are test fixtures, not application defaults, and copying them into a deployment would be a mistake.

## Where Kysely stops: no models, no relations, no schema sync

Kysely is not an ORM, and the README never claims otherwise. There are no model classes, no lazy-loaded relations, no identity map, and no change tracking. You get a builder that produces SQL and a result type shaped like the rows you selected. Everything above that layer is yours to write.

The schema interface is hand-maintained or generated separately. Nothing in the package inspects your database and updates your types. That is the trade: full control over the SQL text, and an ongoing obligation to keep the type definitions honest.

Migrations exist but are a module, not a framework. The exports map lists ./migration, so migration code is imported from a subpath rather than the root. The README does not document rollback behavior, and it does not describe how migrations are discovered or ordered. If your team needs a migration tool with a documented down path and a CLI, read the migration module's own documentation before assuming Kysely covers it.

The last push to the repository was on 2026-08-10, the same day v0.29.5 was released. There is a v0.30.0-beta line, with 0.30.0-beta.0 and 0.30.0-beta.1 published in July 2026, so a major-version change is in progress; the README and package.json describe 0.29.5 as current.

## Kysely compared with Knex, Drizzle and Prisma

Against Knex, the difference is the type layer, not the query style. Both are query builders, and Kysely's README credits Knex as its inspiration and lists Knex's author, Tim Griesser, among the people with special impact on the project. Knex gives you a builder without compile-time knowledge of your tables; Kysely's whole premise is that the builder knows them.

Against Prisma, the difference is direction of control. Prisma generates a client from a schema file and gives you model objects and relations. Kysely gives you no generated client and no models; you supply the Database interface and write the SQL shape yourself. The README's credits list two people for a Prisma-to-Kysely path, one for the idea and one for prisma-kysely, which suggests the two are used together rather than chosen as pure substitutes.

Against Drizzle, the difference is where types come from. Drizzle's model starts from schema definitions in TypeScript that also drive migrations. Kysely starts from an interface describing tables you already have, and treats migration as a separate concern. If your database is the source of truth and predates your application code, Kysely's starting point fits better. If you want one schema file to generate types, migrations and queries, Kysely will feel like two tools.

## Licence, maintenance and the cost of upgrading

Kysely is MIT licensed, per the LICENSE file and the repository metadata. That permits commercial use and modification, and it carries no copyleft obligation on your application code. This is a description of the licence text, not legal advice; if your organisation has a licence review process, the file is short enough to read directly.

The maintenance signal is the commit history, not the release count. The last push was on 2026-08-10, and v0.29.5 was released the same day. The 0.30.0-beta releases in July 2026 indicate work on a new minor line, but the README still describes the 0.29.x behaviour.

The upgrade cost has two parts. First, the engines field: node >=22.0.0 is a hard floor, so older runtimes cannot install the current package. Second, the typesVersions and exports maps route TypeScript below 5.4 to outdated-typescript.d.ts. That file exists so old compilers get a degraded definition rather than a broken build, which means the type inference described in the README is not what a pre-5.4 TypeScript project will experience. Upgrading TypeScript is part of upgrading Kysely.

## When Kysely is the wrong choice

If your team does not write SQL today and does not want to start, Kysely adds a vocabulary you must learn before you ship anything. The README's own framing is a query builder for people who already think in queries.

If your application is mostly CRUD over a schema you control end to end, an ORM's generated client will produce less code for the same result. Kysely will not generate the queries for you, and it will not generate the types either unless you add a separate codegen tool.

If you rely on a type-safe query layer inside raw SQL fragments, be aware that the escape hatches are exactly that. The README points to the sql template tag and DynamicModule for cases that "cannot be typed at compile time." Code inside those fragments is outside the checking the rest of the library provides, and a wrong column name there behaves like ordinary SQL.

Finally, if you need a documented rollback story for migrations, verify it before adopting. The README does not document rollback, and the migration module is a subpath export whose behaviour you should read up on directly.

## Conclusion

Adopt Kysely if your team writes SQL deliberately and wants the compiler to catch wrong table and column names, and if you are willing to maintain a hand-written database interface. Do not adopt it if you want model classes, relations and migrations generated for you; that is an ORM's job, and Kysely's migration module only runs migration files you write. Before committing, check the engines field in package.json against your Node version, confirm your dialect has a helper under kysely/helpers, and decide how your Database interface will be kept in sync with the real schema.

## FAQ

### How do you pronounce "Kysely"?

The README gives the pronunciation as "Key-Seh-Lee".

### Is Kysely an ORM?

No. The README describes it as a type-safe SQL query builder, and there are no model classes or relations in the API it documents.

### What is Kysely?

It is a type-safe and autocompletion-friendly TypeScript SQL query builder, mainly developed for Node.js and also running on Deno, Bun, Cloudflare Workers and web browsers.

### What are the differences between Kysely and Knex?

Kysely's README states it was inspired by Knex.js, and it lists Knex's author among the people who had special impact on the project. The distinction Kysely draws is the type layer: it checks that you only refer to tables and columns visible to the part of the query you are writing.

### What is Kysely used for?

For writing SQL queries in TypeScript where table and column names are checked by the compiler, and where the result type contains only the selected columns with their types and aliases.

## Sources

- [Official documentation](https://kysely.dev)
- [Official README](https://github.com/kysely-org/kysely#readme)
- [Project repository](https://github.com/kysely-org/kysely)
- [Release notes](https://github.com/kysely-org/kysely/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/kysely-org-kysely
