SQLDelight: typesafe Kotlin APIs generated from your SQL
SQLDelight - Generates typesafe Kotlin APIs from SQL
At a glance
- What is it?
- SQLDelight compiles .sq files into Kotlin interfaces, checking schema, statements and migrations at build time. It suits Kotlin Multiplatform projects that want SQL, not an ORM, and it is a poor fit if you want runtime query building.
- Who is it for?
- Adopt SQLDelight if you already write SQL by hand, want compile-time verification, and need one query layer across Android, iOS, JVM, JS or native targets. Do not adopt it if you rely on runtime query construction, or if your team has no appetite for Gradle code generation and schema migration files.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly Kotlin, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem SQLDelight solves for Kotlin teams
Android and Kotlin Multiplatform projects usually end up with SQL in one of two places: string constants scattered through repositories, or an ORM that hides the query behind an object graph. The first gives you no compile-time check that a column name is still correct. The second gives you a query planner you cannot see and a mapping layer you did not write.
SQLDelight takes a third position. You keep writing SQL, in files with a .sq extension, and the Gradle plugin generates Kotlin from them. The README states the project "verifies your schema, statements, and migrations at compile-time and provides IDE features like autocomplete and refactoring". The audience is therefore narrow and specific: teams that are comfortable with SQL and want the compiler to catch a renamed column before the app ships, rather than at runtime in a crash report.
The README also notes that SQLDelight "understands your existing SQL schema", which matters for anyone migrating an app that already has CREATE TABLE statements. The input is your schema, not a Kotlin data class that gets mapped to a table.
How the .sq files, dialects and drivers fit together
The repository is organised around four moving parts. The sqldelight-compiler module parses SQL and emits Kotlin. The sqldelight-gradle-plugin wires that generation into your build. The dialects directory holds the SQL dialects (SQLite, MySQL, PostgreSQL, and an experimental HSQL/H2 dialect). The drivers directory holds the runtime implementations for each platform.
The README lists the supported combinations explicitly. SQLite is available for Android, Native (iOS, macOS or Windows), JVM, JavaScript, and a Multiplatform target. MySQL and PostgreSQL are JVM only. HSQL/H2 is JVM and marked Experimental. That table is the real constraint on adoption: a Kotlin Multiplatform project targeting iOS and Android can share SQLite queries, but a project that needs PostgreSQL on the server and SQLite on the client is working with two dialects and two generated APIs.
A labeled statement is what produces a Kotlin function. The README shows a schema declaration and says SQLDelight "generates typesafe code for any labeled SQL statements". The label becomes the method name, and the columns in the SELECT determine the return type. The sqldelight-idea-plugin entry in the repository root is the IDE side of the same information, which is where autocomplete and refactoring come from.
Adding SQLDelight to a Gradle build and running a first query
The README points to the project website rather than giving install steps inline, so the authoritative setup instructions live at sqldelight.github.io/sqldelight. The repository does ship a sample directory with a Gradle build, and the plugin is published as sqldelight-gradle-plugin. The shape of the setup is a plugin declaration plus a databases block that names your package and schema output.
plugins {
id("app.cash.sqldelight") version "2.4.0"
}
sqldelight {
databases {
create("Database") {
packageName.set("com.example.db")
}
}
}The version above is the 2.4.0 release dated 2026-09-18 in the repository's release list. After a Gradle sync, the plugin looks for .sq files under the configured source set and generates a Kotlin interface named after the database. Your first .sq file is where the schema goes, and the README's own example uses a hockey_player table.
CREATE TABLE hockey_player (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
number INTEGER NOT NULL
);
selectAll:
SELECT * FROM hockey_player;The label selectAll is the generated function name. What you should see after building is a generated Kotlin file exposing that query as a function returning a typed result, plus a driver you instantiate for your platform. The README does not document rollback behaviour for migrations, so check the migration documentation on the project site before relying on it.
Where SQLDelight gets in the way
The generation step is the main cost. Every schema change means a rebuild before the Kotlin API reflects it, and a schema change that breaks a statement is surfaced as a compile error rather than a runtime one. That is the point of the tool, but it also means your build now has a code generation phase that can fail for reasons unrelated to your Kotlin code.
Migrations are the sharpest edge. The README claims migrations are verified at compile time, but it does not document rollback, and the repository carries a separate sqlite-migrations directory, which suggests migration handling is treated as its own concern rather than a one-line setting. If your app ships to users who cannot reinstall, you need to read the migration documentation in full before adopting.
The dialect matrix is the second limit. HSQL/H2 is labeled Experimental in the README, so treating it as production-ready is not supported by the project's own description. MySQL and PostgreSQL support is JVM only, which rules out sharing those queries with an iOS or JavaScript target. And if your queries are assembled at runtime from user-selected filters, SQLDelight is the wrong tool: it generates from statements that exist at build time.
SQLDelight compared with Room and Exposed
Room is the common alternative on Android, and the comparison is about where the SQL lives. Room maps annotated Kotlin classes and DAO interfaces to tables, and it verifies queries against the schema at compile time too. SQLDelight starts from the SQL file and generates the Kotlin, so the SQL is the source of truth rather than the annotation. Room is Android-first; SQLDelight's README lists Android, Native, JVM, JavaScript and a Multiplatform target for SQLite, which is the difference that decides the choice for a Kotlin Multiplatform codebase.
Exposed is a different shape again: a Kotlin DSL for building queries, aimed at JVM server work. With Exposed you compose queries in Kotlin at runtime. With SQLDelight you write the statement and the compiler checks it. If you want dynamic query construction, Exposed's model fits better; if you want the SQL visible in a file and verified before the build finishes, SQLDelight fits better. The two are not interchangeable, and the search interest in "sqldelight vs exposed" reflects that people hit this fork in the road.
Against plain SQLite, the difference is the generated layer. The README's own framing is that SQLDelight understands your existing schema, so you are not rewriting the database, only the access path to it.
Licence, releases and the cost of keeping up
SQLDelight is Apache-2.0, and the README carries the full Apache text with Copyright 2016 Square, Inc. Apache-2.0 permits commercial use and modification, and it includes a patent grant. It also requires that you retain the licence and notice files for the parts you redistribute, and it provides no warranty. That is a description of the licence terms, not legal advice; if you redistribute generated code or bundle the runtime, have your own counsel review the notice obligations.
The release cadence visible in the repository is not fast. 2.4.0 landed on 2026-09-18, 2.3.2 on 2026-03-16, and 2.2.1 on 2025-11-14. The last push to the default branch was on 2026-09-21. Upgrade cost is concentrated in the Gradle plugin version and the dialect you target, because the generated API follows the statements you wrote. A minor bump that changes generated signatures will show up as compile errors across your query call sites, which is the trade for compile-time checking. Pin the plugin version in your build and read CHANGELOG.md before moving it.
Editorial conclusion
Adopt SQLDelight if you already write SQL by hand, want compile-time verification, and need one query layer across Android, iOS, JVM, JS or native targets. Do not adopt it if you rely on runtime query construction, or if your team has no appetite for Gradle code generation and schema migration files. Before committing, verify that your target dialect and driver combination is listed in the documentation, and check the CHANGELOG for the migration behaviour of the version you pin.
Frequently asked questions
What is SQLDelight?
It is a tool that generates typesafe Kotlin APIs from SQL statements and verifies your schema, statements and migrations at compile time, according to the README. It ships as a compiler, a Gradle plugin, an IDE plugin and platform drivers.
Can I use SQLite with Kotlin?
Yes. SQLDelight's README lists SQLite support for Android, Native (iOS, macOS or Windows), JVM, JavaScript and a Multiplatform target, each with its own driver.
How does SQLDelight compare with SQLite on its own?
SQLDelight does not replace the database. The README states it understands your existing SQL schema and generates typesafe code for labeled statements, so SQLite remains the engine and SQLDelight is the generated access layer.
How does SQLDelight compare with Room?
Room maps annotated Kotlin classes and DAO interfaces to tables, while SQLDelight generates Kotlin from .sq files, making the SQL the source of truth. The README lists Android, Native, JVM, JavaScript and Multiplatform targets for SQLite, which matters if you are not Android-only.
How does SQLDelight compare with Exposed?
Exposed is a Kotlin DSL for composing queries at runtime, while SQLDelight generates from statements that exist at build time. The README's dialect list puts MySQL and PostgreSQL support on the JVM only.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/sqldelight-sqldelight)