Library / SDK
zio/zio-quill avatar
zio/zio-quill

zio-quill: Scala queries that compile down to SQL and CQL

Compile-time Language Integrated Queries for Scala

2,166 stars352 forksScalaApache-2.0

At a glance

What is it?
A Scala library that reads queries out of quotation blocks at compile time and hands the target database a string, so nothing about query building survives into your running process.
Who is it for?
Quill earns its place in codebases where the same query logic is exercised against several database engines, because the quotation is portable where hand-written strings are not. What the README settles is the architecture: quote blocks, compile-time translation, optional compile-time validation against a real database.
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 2 days ago.
What is it written in?
Mainly Scala, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the quoted block removes from your data layer

The pitch of Quill is narrow and unusual: write the query inside a `quote` block using Scala that looks like Scala, and let the compiler work out what the database should receive. The README names the technique a Quoted Domain Specific Language and points at Philip Wadler's language-integrated query talk as the origin, with two academic papers on the quoted approach and on flatter query construction listed as further reading. That lineage explains the shape better than the feature list does.

What you give up is the familiar ORM vocabulary. There is no `where` method chaining and no lazy query object that assembles itself as you traverse it. Instead, the block is a quotation, and the quotation is inspected during compilation and turned into an internal syntax tree. The README states the payoff directly: because the query string is known at compile time, the runtime cost is similar to calling the driver yourself. For a service where every query is on a hot path, that is the argument that decides the matter, and it is the argument a string-building ORM cannot make.

How the compiler gets from quotation to query string

The mechanism is a `ctx.run` call. The README describes it as reading the quotation's syntax tree and translating it to the target language during compilation, emitting the finished query as a compilation message. Emitting the SQL as a compiler message is the detail that makes the library feel unusual in practice: open the build log and you can read every query your code will ever send, with no debugger and no logging configuration.

Because the tree exists before the program runs, the translation can fail the build rather than the request. The README lists compile-time query validation as a separate capability: when configured, the query is checked against the database during compilation and the build fails if it is invalid. It also notes that validation does not change database state, which matters more than it sounds. A schema check that only reads, run on every compile, catches column renames and type mismatches in a pull request rather than in production traffic.

The one cost is obvious once you meet it in a real project. Since the query must be provable at build time, dynamic fragments such as a column chosen by a runtime variable cannot be expressed the way they can in a builder API. You end up writing a small branch per shape and letting the compiler generate one query per branch, which is exactly the trade the library asks you to make.

One directory per backend, and what the tree reveals

The repository is organised so the module names are the answer to which backend you use. `quill-core/` holds the language-independent machinery, `quill-sql/` and `quill-cassandra/` hold the target languages, and `quill-codegen/` with `quill-codegen-jdbc/` handle code generation. The effect modules follow: `quill-jdbc/` and `quill-jdbc-zio/` for JDBC with and without ZIO, `quill-doobie/` for Doobie, `quill-zio/` for the ZIO context itself, `quill-spark/` for Spark SQL, and `quill-orientdb/` for OrientDB.

The test modules are the most informative part of the tree, because they name every database the library claims to work against. There are separate `quill-jdbc-test-*` modules for H2, MySQL, Oracle, Postgres, SQLite and SQL Server, plus `quill-sql-test/` for the shared SQL suite. Reading that list tells you which combinations get exercised on every commit. It also tells you what the README does not: Cassandra has its own top-level module plus a Pekko-backed variant, so the CQL side is a first-class target rather than a JDBC afterthought.

The repository also carries the usual ZIO project furniture: `build.sbt`, `project/`, `codecov.yml`, a `.scalafmt.conf`, `docs/` and `scripts/`. The README itself opens with a comment saying it is autogenerated by the `zio-sbt-website` plugin from `docs/index.md`, which is a useful thing to know before you file a documentation pull request against the wrong file.

Docker Compose as the integration test fixture

Running the database-specific test suites needs real engines, and the repository keeps them in `docker-compose.yml`. The ports are deliberately non-standard so several engines can run side by side on a laptop without colliding with anything already listening.

yaml
  postgres:
    image: postgres:9.6
    ports:
      - "15432:5432"

MySQL carries a comment explaining that version 8.0.23 is pinned because it ships ARM64 images for M1 Macs, and there is a separate `docker-compose-m1.yml` alongside it. Cassandra and SQL Server are not pulled from a public registry at all; both are built locally from `build/Dockerfile-cassandra` and `build/Dockerfile-sqlserver`.

yaml
  cassandra:
    build:
      context: .
      dockerfile: ./build/Dockerfile-cassandra
    ports:
      - "19042:9042"

The OrientDB service records a fix in a comment: version 3.0.42 refused to stay up during local testing, so the compose file and `build.sbt` were both bumped to 3.2.6. Small notes like that are usually the most useful lines in a compose file, because they tell you which engine is the awkward one before you spend an afternoon on it.

Two cautions about this fixture. The Postgres image is 9.6, which is long past end of life, so it is a compatibility target rather than a recommendation for your own deployment. And the compose file ends mid-entry on the Oracle service, whose image is a community-built `oracle-18-xe-micro-sq` on port 11521, so the Oracle settings are not fully legible here and should be read from the file directly.

Scala 3 support lives in a different repository

This is the point where the README and the artifact coordinates disagree, and the disagreement matters. The Maven badges at the top of the README point at `io.getquill/quill-core_2.12`, which is the Scala 2.12 line. A note below the introduction then says that Scala 3 support is provided by ProtoQuill in `zio/zio-protoquill`, rebuilt on newer metaprogramming facilities, and published as the `quill-<module>_3` artifact line.

Both statements are accurate at once, and together they describe a project whose published coordinates are split across two repositories by Scala version. If you are on Scala 2.13 you can use the main artifacts, but the badge you will naturally copy from the README is the 2.12 one, so check which cross version your build resolves before assuming the dependency you added is the one the maintainers intend for your Scala version. Readers who take the badge literally end up on the oldest supported line.

The second disagreement is about the license link. The README closes with a link labelled License pointing at `LICENSE`, while the repository tree lists `LICENSE.txt`. The repository metadata field reports Apache-2.0, which matches what the ZIO organisation publishes elsewhere, so the file name is the outlier rather than the license choice.

Reading the release history before you pin a version

The release list is short and uneven. v4.8.4 shipped on 2024-05-07, v4.8.5 on 2024-11-24, and v4.8.6 on 2025-07-17. The last of those notes is almost entirely dependency bumps: zio-json, sbt, logback-classic, HikariCP, scalafmt, plus Dependabot and zio-scala-steward entries.

Put that beside the push date of 2026-09-27 and the picture is a project that is still being worked on at roughly the fourteen month mark after its most recent tag. That is a real gap between what the repository shows and what Maven Central offers, and it is worth naming rather than smoothing over, because it changes what you pin. Anyone starting today is choosing between the newest published 4.8.x artifact and source that has moved on since, and there is no 4.9 tag to arbitrate. Reading the commit log on `master` is the only way to see what you would be gaining or risking.

The maintainer list supports the picture of an active project with a stable core team. The README names @deusaquilus as lead maintainer, @fwbrasil as creator, and @jilen, @juliano, @mentegy and @mdedetrich alongside them, with a `@getquill/maintainers` handle for reaching all of them at once. v4.8.5 also shows @deusaquilus shipping a functional fix to `onConflict` when an existing column is used, and v4.8.4 predates ProtoQuill. The maintainers are visibly doing maintenance work, not just triage.

Editorial conclusion

Quill earns its place in codebases where the same query logic is exercised against several database engines, because the quotation is portable where hand-written strings are not. What the README settles is the architecture: quote blocks, compile-time translation, optional compile-time validation against a real database. What it leaves open is the version story, since the newest tagged release is v4.8.6 from 2025-07-17 while the repository itself was pushed on 2026-09-27. Start by adding `quill-core` plus one backend module and writing a single `ctx.run` call, then decide whether compile-time validation against a live container is a gate you want in your build.

Frequently asked questions

What does Quill do that a normal Scala ORM does not?

Quill reads query code out of a quotation at compile time and emits the finished SQL or CQL as a compiler message, instead of assembling a query object at runtime through chained methods. The practical difference is that no query-building cost survives into the running process, and an invalid query can fail the build rather than a request.

Which databases does zio-quill actually support?

SQL and CQL are the two target languages named in the README. The repository tree backs that up with one module per engine: JDBC test modules for H2, MySQL, Oracle, Postgres, SQLite and SQL Server, plus dedicated Cassandra and OrientDB modules and a Spark SQL module.

How do I use zio-quill from Scala 3?

The README points Scala 3 users at ProtoQuill in the zio/zio-protoquill repository, which rebuilds the library on newer metaprogramming facilities and publishes a separate `quill-<module>_3` artifact line. The Maven badges in this README point at the Scala 2.12 line, so pick the coordinates that match your Scala version rather than copying the badge URL.

Does Quill validate queries against the database at compile time?

Yes, if you configure it. The README states that a query is verified against the database during compilation and the build fails when the query is invalid, and that this validation does not change database state. It is opt-in, and it needs a reachable database when the module compiles.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. zio/zio-quill on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/zio-zio-quill.svg)](https://hysenlabs.com/projects/zio-zio-quill)