Skip to main content

Kebs

Scala library for eliminating boilerplate.

Zero boilerplate

Stop writing MappedColumnType.base, deriveEncoder, and Unmarshaller.strict for every wrapper type. Kebs derives all of that at compile time from a single typeclass.

Use strong types everywhere

Value classes, opaque types, tagged types, and enums just work with Slick, Doobie, Circe, Spray JSON, Play JSON, Akka HTTP, Pekko HTTP, http4s, ScalaCheck, PureConfig, and more.

Scala 2 & 3

Full cross-build support for Scala 2.13 and Scala 3, including JVM, Scala.js, and Scala Native where applicable.

Without Kebs

case class UserId(value: String) extends AnyVal
case class Email(value: String) extends AnyVal

// Slick
implicit val userIdCol: BaseColumnType[UserId] =
MappedColumnType.base(_.value, UserId.apply)
implicit val emailCol: BaseColumnType[Email] =
MappedColumnType.base(_.value, Email.apply)

// Circe
implicit val userIdEnc: Encoder[UserId] =
Encoder[String].contramap(_.value)
implicit val userIdDec: Decoder[UserId] =
Decoder[String].map(UserId.apply)
// ... repeat for every type × every library

With Kebs

case class UserId(value: String) extends AnyVal
case class Email(value: String) extends AnyVal

// That's it. Slick, Circe, Akka HTTP, Doobie,
// http4s, Play JSON, etc. all just work.

Quick start

// build.sbt — pick the modules you need
libraryDependencies ++= Seq(
"pl.iterators" %% "kebs-circe" % kebsVersion,
"pl.iterators" %% "kebs-slick" % kebsVersion,
"pl.iterators" %% "kebs-pekko-http" % kebsVersion,
"pl.iterators" %% "kebs-instances" % kebsVersion
)