Welcome to the Wonderful World of Skunk! This section will help you get everything set up.

Database Setup

In order to run the tutorial examples you will need a Postgres server with the world database loaded up, writable by the jimmy user, who must be able to log in with password banana. Our Docker image does exactly that.

docker run -p5432:5432 -d tpolecat/skunk-world

If you wish to use your own Postgres server you can download world/world.sql from the Skunk repository and load it up yourself.

Scala Setup

Create a new project with Skunk as a dependency.

libraryDependencies += "org.tpolecat" %% "skunk-core" % "0.6.4"

IDE Setup

For metals, no additional steps are needed.

For IntelliJ, add the skunk-intellij plugin to have correct code highlighting support for statements.

Verify Your Setup

Try out this minimal IOApp that connects to the database and selects the current date.

import cats.effect._
import skunk._
import skunk.implicits._
import skunk.codec.all._
import natchez.Trace.Implicits.noop                          // (1)

object Hello extends IOApp {

  val session: Resource[IO, Session[IO]] =
    Session.single(                                          // (2)
      host     = "localhost",
      port     = 5432,
      user     = "jimmy",
      database = "world",
      password = Some("banana")

  def run(args: List[String]): IO[ExitCode] =
    session.use { s =>                                       // (3)
      for {
        d <- s.unique(sql"select current_date".query(date))  // (4)
        _ <- IO.println(s"The current date is $d.")
      } yield ExitCode.Success


Let's examine the code above.

When we run the program we see the current date.

The current date is 2024-06-05.


Here are some modifications that will cause runtime failures. Give them a try and see how Skunk responds.

We will see more examples later in the tutorial.