Skip to main content
Version: 2.0.x


Distage is a compile-time safe, transparent, and debuggable Dependency Injection framework for pure FP Scala.


By using Distage we can auto-wire all components of our application.

  • We don't need to manually link components together
  • We don't need to manually specify the order of allocation and allocation of dependencies. This will be derived automatically from the dependency order.
  • We can override any component within the dependency graph.
  • It helps us to create different configurations of our components for different use cases.


In order to use this library, we need to add the following line in our build.sbt file:

libraryDependencies += "io.7mind.izumi" %% "distage-core" % "1.0.8"


In this example we create a RandomApp comprising two Random and Logger services. By using ModuleDef we bind services to their implementations:

import distage.{Activation, Injector, ModuleDef, Roots}
import izumi.distage.model.Locator
import izumi.distage.model.definition.Lifecycle
import zio.{ExitCode, Task, UIO, URIO, ZIO}

import java.time.LocalDateTime

trait Random {
def nextInteger: UIO[Int]

final class ScalaRandom extends Random {
override def nextInteger: UIO[Int] =

trait Logger {
def log(name: String): Task[Unit]

final class ConsoleLogger extends Logger {
override def log(line: String): Task[Unit] = {
val timeStamp =
ZIO.effect(println(s"$timeStamp: $line"))

final class RandomApp(random: Random, logger: Logger) {
def run: Task[Unit] = for {
random <- random.nextInteger
_ <- logger.log(s"random number generated: $random")
} yield ()

object DistageExample extends zio.App {
def RandomAppModule: ModuleDef = new ModuleDef {
make[RandomApp] // `.from` is not required for concrete classes

val resource: Lifecycle[Task, Locator] = Injector[Task]().produce(
plan = Injector[Task]().plan(
bindings = RandomAppModule,
activation = Activation.empty,
roots =[RandomApp]

val myApp: Task[Unit] = resource.use(locator => locator.get[RandomApp].run)

override def run(args: List[String]): URIO[zio.ZEnv, ExitCode] =