Library / SDK
slick/slick avatar
slick/slick

Slick (Scala Language Integrated Connection Kit): a review for Scala teams

Slick (Scala Language Integrated Connection Kit) is a modern database query and access library for Scala

2,665 stars611 forksScalaBSD-2-Clause

At a glance

What is it?
Slick is a Scala database access library that compiles Scala queries into SQL for nine supported engines. This review covers how the query compiler works, how to install it, and where it stops being the right tool.
Who is it for?
Adopt Slick if your team writes Scala and wants column and query errors caught at compile time while keeping the option to drop to raw SQL. Do not adopt it if you need a schema-first migration tool or a non-Scala service; Slick is a query and access layer, not a migration framework.
Can I use it commercially?
Yes. BSD-2-Clause 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 8 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 September 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem Slick solves for Scala teams

Slick targets a specific gap: writing SQL as strings inside Scala code loses the type checker. A column renamed in the database breaks nothing until the query runs in production. Slick's answer is to represent tables and columns as Scala values, so the compiler sees them. A filter on a column that does not exist is a compile error, not a runtime exception.

The audience is Scala developers who already think in collections and want database access to look similar. The README describes the goal directly: it lets you "work with relational databases almost as if you were using Scala collections, while at the same time giving you full control over when the database is accessed and how much data is transferred." That second half matters. Slick is not an ORM that hides the database behind lazy object graphs. You decide when a query runs and what it returns.

It is a poor fit for teams that want schema management included. Slick gives you a query and access layer, and the repository separates that concern: code generation lives in slick-codegen, not in the core module. If you expect migrations from the same library, you will be looking elsewhere.

How the query compiler turns Scala into SQL

The central mechanism is a compiler that translates Scala expressions into SQL for different engines. You write a query once; Slick emits the dialect-specific SQL. The README frames this as the reason the same Scala code works across engines: "an advanced query compiler which can generate SQL for a variety of different database engines from the same Scala code."

The mapping starts with a Table class. Each column is declared with a type and a database column name, and the `*` projection maps the columns to a case class. A TableQuery wraps that table and exposes the collection-like API. From there, `+=` inserts, `map` projects, `filter` and `sortBy` restrict and order. The README annotates each operation with the SQL it produces, which is the clearest signal of intent: the Scala is the source of truth and SQL is the output.

Execution is explicit. The asynchronous API is built on Cats Effect 3, and `db.run(action)` returns `F[R]` for any effect type with a `cats.effect.Async` instance, such as `cats.effect.IO` or ZIO `Task`. Streaming goes through FS2 as `Stream[F, T]`. Composition happens at three levels: actions in for comprehensions, queries in for comprehensions or combinators, and row expressions as column sets and predicates. That layering is where the library earns its complexity budget, and also where newcomers get lost.

Installing Slick and running a first query

Slick publishes to Maven Central under the group `com.typesafe.slick`, with artifacts suffixed by the Scala version, for example `slick_2.13`. Add the dependency and the JDBC driver for your database to your build. The README lists the driver coordinates it tests against, including PostgreSQL at `"org.postgresql" % "postgresql" % "42.7.10"` and SQLite at `"org.xerial" % "sqlite-jdbc" % "3.51.3.0"`.

scala
libraryDependencies ++= Seq(
  "com.typesafe.slick" %% "slick" % "3.6.1",
  "org.postgresql" % "postgresql" % "42.7.10"
)

The README's example imports the PostgreSQL profile, declares a case class, a Table, and a TableQuery. Note that the import uses the wildcard form shown in the README.

scala
import slick.jdbc.PostgresProfile.api.*

final case class Coffee(name: String, price: Double)

class Coffees(tag: Tag) extends Table[Coffee](tag, "COFFEES") {
  def name  = column[String]("NAME")
  def price = column[Double]("PRICE")
  def * = (name, price).mapTo[Coffee]
}

val coffees = TableQuery[Coffees]

From there the query API reads like collection code. The README shows an insert and a filter with the SQL each produces, so you can check the generated statement against what you expected.

scala
coffees += Coffee("Latte", 2.50)

coffees.filter(_.price < 10.0).sortBy(_.name)

If you want the table classes generated from an existing database rather than written by hand, that is the job of the separate slick-codegen module. The core README does not walk through it, so treat code generation as a second step with its own documentation.

For local testing, the repository ships a docker-compose.yml with services for postgres, oracle, sqlserver, db2 and mysql. Postgres maps host port 5432 and sets POSTGRES_PASSWORD to postgres, so a local instance is one `docker compose up postgres` away.

Where Slick is the wrong tool

The abstraction has a ceiling. When a query needs a database-specific feature the compiler cannot express, you drop to raw SQL. The README acknowledges this: Slick retains "the ability to drop down to raw SQL when necessary for custom or advanced database features." That escape hatch is honest, but it means the type safety guarantee stops at the boundary. A hand-written SQL fragment is exactly as unverified as it would be without Slick.

Database coverage is another boundary. Nine engines are listed as directly supported and covered by an automated test suite. Everything else is possible "although possibly with a reduced feature set." If you run an engine outside that table, you are working against the grain, and the compiler may generate SQL your database rejects.

There is also a versioning cost. The current release line is 4.0.0-RC2, published on 2026-09-07, with 4.0.0-RC1 before it on 2026-06-19. The last stable release in the list is 3.6.1 from 2025-05-16. A team that cannot run release candidates should plan around the 3.x line and check what the 4.0 line changes before moving, particularly given the Cats Effect 3 and FS2 APIs described in the README. The repository is not archived and the last push was on 2026-09-23, but the release channel is the more useful signal here.

Finally, Slick is a library, not a platform. There is no migration runner, no connection pool of its own in the core module (the repository carries a separate slick-hikaricp module for that), and no admin surface. Teams expecting a batteries-included data layer will find themselves assembling pieces.

Slick compared with writing SQL by hand

The real alternative for most Scala teams is not another library but plain JDBC with string SQL. The difference in approach is where errors surface. With hand-written SQL, a typo in a column name or a mismatch between the query and the case class you map it into is a runtime failure. With Slick, the table definition and the query are both Scala values, so the compiler checks the shape of the result before the code runs.

The trade is visible in the example above. Writing a Table class plus a case class plus a TableQuery is more code than one SQL string and a row mapper. Slick asks you to pay that up front and collect the benefit on every later change. For a small service with a handful of queries, the up-front cost may not pay back. For a codebase where the schema moves and queries are numerous, the compile-time check is the whole point.

The other genuine difference is portability. Hand-written SQL is bound to one dialect. Slick's compiler emits SQL per engine from the same source, which is why the README can claim the same Scala code targets many databases. If you only ever run PostgreSQL, that portability is unused weight, and the raw-SQL escape hatch is where you will spend your time anyway.

Maintenance, licensing and upgrade cost

Maintenance is community-driven. The README states plainly that "Slick is community-maintained: pull requests are very welcome," and points contributors at the Lightbend Community Code of Conduct. Lightbend staff may assist with administrative issues. That is a lighter commitment than a vendor-backed library, and it is worth weighing if you need a support contract.

The repository's activity signals are mixed but current: the last push was on 2026-09-23, and the 4.0.0 release candidates landed in June and September 2026. Automation is in place for dependency updates, with both .scala-steward.conf and renovate.json at the top level, plus a .mergify.yml for merge automation. Those files suggest routine upkeep rather than a dormant project.

On licensing, Slick is BSD-2-Clause. That is a permissive licence, and the repository ships LICENSE.txt at the top level. I am not a lawyer and this is not legal advice, but the practical implication of a two-clause BSD licence is that you can use and redistribute the library with the copyright notice retained, and there is no copyleft obligation on your own code. Verify the current LICENSE.txt text yourself rather than relying on the licence identifier alone.

The upgrade cost is the part teams underestimate. The 3.x to 4.0 transition involves the asynchronous API described in the README, built on Cats Effect 3, and the FS2 streaming API. If your code sits on the older interfaces, expect the effect type and streaming signatures to be where the work concentrates. Check the release notes for 4.0.0-RC2 rather than assuming the migration is mechanical.

Editorial conclusion

Adopt Slick if your team writes Scala and wants column and query errors caught at compile time while keeping the option to drop to raw SQL. Do not adopt it if you need a schema-first migration tool or a non-Scala service; Slick is a query and access layer, not a migration framework. Before committing, verify three things against your own database: that code generation produces the table classes you expect, that your JDBC driver version appears in the supported list, and that your queries compile rather than silently falling back to a runtime failure.

Frequently asked questions

What is Slick (the Scala database library) and who is it for?

Slick is a database access library for Scala with strongly-typed, composable APIs and a query compiler that generates SQL for multiple database engines. It is aimed at Scala developers who want compile-time checking of queries while keeping control over when the database is accessed.

Which databases does Slick support?

The README lists nine directly supported engines covered by an automated test suite: PostgreSQL, MySQL, SQLServer, Oracle, DB2, Derby/JavaDB, H2, HSQLDB/HyperSQL and SQLite. Accessing other database systems is described as possible, possibly with a reduced feature set.

How do I install Slick in a Scala project?

Add the artifact from Maven Central under the group com.typesafe.slick, with the Scala version suffix such as slick_2.13, plus the JDBC driver for your database. The README lists the driver coordinates it tests against, including the PostgreSQL and SQLite drivers.

Does Slick work with Cats Effect and FS2?

Yes. The README describes an asynchronous API built on Cats Effect 3 where db.run(action) returns F[R] for any effect type with a cats.effect.Async instance, and a streaming API returning FS2 Stream[F, T].

What licence does Slick use?

Slick is released under BSD-2-Clause, and the repository includes LICENSE.txt at the top level. That is a permissive licence; check the licence text itself if the terms matter to your organisation.

Official sources

  1. License: BSD-2-Clause
  2. Project website
  3. README
  4. Releases
  5. slick/slick 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/slick-slick.svg)](https://hysenlabs.com/projects/slick-slick)