ZIO is a zero-dependency Scala library for asynchronous and concurrent programming with comprehensive effect system.
npx @tessl/cli install tessl/maven-dev-zio--zio_2-12@2.1.0ZIO is a zero-dependency Scala library for asynchronous and concurrent programming, powered by highly-scalable, non-blocking fibers. It provides a comprehensive effect system with the core ZIO[R, E, A] type representing async workflows that require an environment R and can fail with E or succeed with A. ZIO features high-performance concurrent operations, type-safe error handling, resource management that prevents leaks, comprehensive testing capabilities, and functional programming primitives.
libraryDependencies += "dev.zio" %% "zio" % "2.1.19"import zio._
import zio.ZIO._For specific components:
import zio.{ZIO, ZLayer, Runtime, Fiber, Ref, Queue, Schedule, Cause, Chunk}
import zio.stm.{ZSTM, TRef, TMap, TQueue}
import zio.stream.{ZStream, ZSink, ZPipeline}
import zio.test.{Spec, ZIOSpecDefault, Assertion, Gen, TestAspect}
import zio.metrics.{Metric, MetricClient, MetricLabel}import zio._
// Simple effect that always succeeds
val greeting: UIO[String] = ZIO.succeed("Hello, ZIO!")
// Effect that might fail
val mayFail: IO[String, Int] = ZIO.attempt {
"123".toInt // Could throw NumberFormatException
}.refineOrDie {
case _: NumberFormatException => "Invalid number"
}
// Combining effects
val program: ZIO[Any, String, Unit] = for {
message <- greeting
number <- mayFail
_ <- Console.printLine(s"$message Number: $number")
} yield ()
// Running the program
object MyApp extends ZIOAppDefault {
def run = program
}ZIO is built around several key architectural components:
ZIO[R, E, A] type representing typed effects with environment, error, and success typesZLayer for composable service provisioningZIO provides a rich type alias system for common effect patterns:
// Core effect types
type IO[+E, +A] = ZIO[Any, E, A] // No requirements
type Task[+A] = ZIO[Any, Throwable, A] // May fail with Throwable
type RIO[-R, +A] = ZIO[R, Throwable, A] // Requires R, may fail
type UIO[+A] = ZIO[Any, Nothing, A] // Cannot fail
type URIO[-R, +A] = ZIO[R, Nothing, A] // Requires R, cannot fail
// Layer type aliases
type RLayer[-RIn, +ROut] = ZLayer[RIn, Throwable, ROut]
type URLayer[-RIn, +ROut] = ZLayer[RIn, Nothing, ROut]
type Layer[+E, +ROut] = ZLayer[Any, E, ROut]
type ULayer[+ROut] = ZLayer[Any, Nothing, ROut]
type TaskLayer[+ROut] = ZLayer[Any, Throwable, ROut]The foundational ZIO effect type and operations for building functional, concurrent applications with comprehensive error handling and resource safety.
sealed trait ZIO[-R, +E, +A] {
// Core transformations
def map[B](f: A => B): ZIO[R, E, B]
def flatMap[R1 <: R, E1 >: E, B](k: A => ZIO[R1, E1, B]): ZIO[R1, E1, B]
def mapError[E2](f: E => E2): ZIO[R, E2, A]
// Error handling
def catchAll[R1 <: R, E2, A1 >: A](h: E => ZIO[R1, E2, A1]): ZIO[R1, E2, A1]
def orElse[R1 <: R, E2, A1 >: A](that: => ZIO[R1, E2, A1]): ZIO[R1, E2, A1]
def retry[R1 <: R, S](policy: => Schedule[R1, E, S]): ZIO[R1, E, A]
// Concurrency
def fork: URIO[R, Fiber.Runtime[E, A]]
def race[R1 <: R, E1 >: E, A1 >: A](that: => ZIO[R1, E1, A1]): ZIO[R1, E1, A1]
def timeout(d: => Duration): ZIO[R, E, Option[A]]
}
// Factory methods
object ZIO {
def succeed[A](a: => A): UIO[A]
def fail[E](error: => E): IO[E, Nothing]
def attempt[A](code: => A): Task[A]
def async[R, E, A](register: (ZIO[R, E, A] => Unit) => Any): ZIO[R, E, A]
}ZLayer system for building and composing services with compile-time dependency resolution and automatic resource management.
sealed abstract class ZLayer[-RIn, +E, +ROut] {
// Composition operators
def ++[E1 >: E, RIn2, ROut2](that: => ZLayer[RIn2, E1, ROut2]): ZLayer[RIn with RIn2, E1, ROut with ROut2]
def >>>[E1 >: E, ROut2](that: => ZLayer[ROut, E1, ROut2]): ZLayer[RIn, E1, ROut2]
def >+>[E1 >: E, ROut2](that: => ZLayer[ROut, E1, ROut2]): ZLayer[RIn, E1, ROut with ROut2]
// Lifecycle
def build: ZIO[RIn with Scope, E, ZEnvironment[ROut]]
def launch: ZIO[RIn, E, Nothing]
}
object ZLayer {
def succeed[A: Tag](a: => A): ULayer[A]
def fromZIO[R, E, A: Tag](zio: => ZIO[R, E, A]): ZLayer[R, E, A]
def scoped[R]: ScopedPartiallyApplied[R]
}Fiber-based lightweight concurrency with atomic data structures for building high-performance concurrent applications.
// Fiber - lightweight threads
sealed abstract class Fiber[+E, +A] {
def await: UIO[Exit[E, A]]
def join: IO[E, A]
def interrupt: UIO[Exit[E, A]]
def zip[E1 >: E, B](that: => Fiber[E1, B]): Fiber.Synthetic[E1, (A, B)]
}
// Ref - atomic reference
sealed abstract class Ref[A] {
def get: UIO[A]
def set(a: A): UIO[Unit]
def modify[B](f: A => (B, A)): UIO[B]
def update(f: A => A): UIO[Unit]
}
// Queue - concurrent queue
sealed abstract class Queue[A] {
def offer(a: A): UIO[Boolean]
def take: UIO[A]
def size: UIO[Int]
}Comprehensive error model with rich failure causes and composable retry/repeat scheduling for resilient applications.
// Rich error representation
sealed abstract class Cause[+E] {
def failures: List[E]
def defects: List[Throwable]
def &&[E1 >: E](that: Cause[E1]): Cause[E1] // parallel composition
def ++[E1 >: E](that: Cause[E1]): Cause[E1] // sequential composition
}
// Retry/repeat scheduling
trait Schedule[-Env, -In, +Out] {
def &&[Env1 <: Env, In1 <: In, Out2](that: Schedule[Env1, In1, Out2]): Schedule[...]
def ||[Env1 <: Env, In1 <: In, Out2](that: Schedule[Env1, In1, Out2]): Schedule[...]
def jittered: Schedule[Env, In, Out]
}
object Schedule {
val forever: Schedule[Any, Any, Long]
def exponential(base: Duration): Schedule[Any, Any, Duration]
def spaced(duration: Duration): Schedule[Any, Any, Long]
}Scope-based resource lifecycle management with automatic cleanup and finalizer execution for leak-free applications.
sealed trait Scope {
def addFinalizer(finalizer: => UIO[Any]): UIO[Unit]
def addFinalizerExit(finalizer: Exit[Any, Any] => UIO[Any]): UIO[Unit]
def fork: UIO[Scope.Closeable]
}
// Resource-safe operations
def acquireRelease[R, E, A, B](
acquire: => ZIO[R, E, A]
)(release: A => URIO[R, Any]): ZIO[R with Scope, E, A]
def ensuring[R1 <: R](finalizer: => URIO[R1, Any]): ZIO[R1, E, A]Lock-free concurrent programming with composable transactional operations and automatic retry mechanisms.
// Transactional effects
sealed trait ZSTM[-R, +E, +A] {
def commit: ZIO[R, E, A]
def map[B](f: A => B): ZSTM[R, E, B]
def flatMap[R1 <: R, E1 >: E, B](f: A => ZSTM[R1, E1, B]): ZSTM[R1, E1, B]
def retry: USTM[Nothing]
}
// Transactional reference
sealed abstract class TRef[A] {
def get: USTM[A]
def set(a: A): USTM[Unit]
def modify[B](f: A => (B, A)): USTM[B]
}
object ZSTM {
def atomically[R, E, A](stm: ZSTM[R, E, A]): ZIO[R, E, A]
}Standard services for common application needs including console I/O, time operations, randomness, and system access.
// Console operations
def printLine(line: => Any): IO[IOException, Unit]
def readLine: IO[IOException, String]
// Time operations
def currentTime(unit: => TimeUnit): UIO[Long]
def sleep(duration: => Duration): UIO[Unit]
def nanoTime: UIO[Long]
// Random generation
def nextInt: UIO[Int]
def nextUUID: UIO[UUID]
def nextBytes(length: => Int): UIO[Chunk[Byte]]
// System access
def env(variable: => String): IO[SecurityException, Option[String]]
def property(prop: => String): Task[Option[String]]Complete application framework with dependency injection, configuration, and lifecycle management for building production applications.
trait ZIOApp {
type Environment
def bootstrap: ZLayer[ZIOAppArgs, Any, Environment]
def run: ZIO[Environment with ZIOAppArgs with Scope, Any, Any]
}
// Default application base
abstract class ZIOAppDefault extends ZIOApp {
type Environment = Any
final def bootstrap: ZLayer[ZIOAppArgs, Any, Any] = ZLayer.empty
}
// Application helpers
def getArgs: ZIO[ZIOAppArgs, Nothing, Chunk[String]]
def exit(code: ExitCode): UIO[Unit]Composable, resource-safe streaming data processing with comprehensive backpressure handling and error recovery for building data pipelines and reactive applications.
// Core streaming types
sealed trait ZStream[-R, +E, +A]
sealed trait ZSink[-R, +E, -In, +L, +Z]
sealed trait ZPipeline[-R, +E, -In, +Out]
// Type aliases
type Stream[+E, +A] = ZStream[Any, E, A]
type UStream[+A] = ZStream[Any, Nothing, A]
// Stream construction
def fromIterable[A](as: => Iterable[A]): UStream[A]
def fromZIO[R, E, A](zio: => ZIO[R, E, A]): ZStream[R, E, A]
def repeat[A](a: => A): UStream[A]Comprehensive testing framework with property-based testing, test services, and seamless integration with ZIO effects for testing concurrent and async code.
// Test specifications
sealed trait Spec[-R, +E]
abstract class ZIOSpec[R] extends ZIOApp
abstract class ZIOSpecDefault extends ZIOSpec[Any]
// Assertions and property testing
sealed trait Assertion[-A]
sealed trait Gen[+R, +A]
def assertTrue(condition: => Boolean): TestResult
def check[R, A](gen: Gen[R, A])(test: A => TestResult): ZIO[R, Nothing, TestResult]
// Test services
trait TestClock extends Clock
trait TestConsole extends Console
trait TestRandom extends RandomComprehensive metrics and observability capabilities for monitoring application performance, collecting telemetry data, and gaining insights into system behavior.
// Metric system
sealed trait Metric[In, Out]
trait MetricClient
case class MetricLabel(key: String, value: String)
// Metric types
def counter(name: String): Metric[Double, MetricState.Counter]
def gauge(name: String): Metric[Double, MetricState.Gauge]
def histogram(name: String, boundaries: Boundaries): Metric[Double, MetricState.Histogram]
// Built-in metrics
val jvmMemoryUsed: Metric[Any, MetricState.Gauge]
val fiberCount: Metric[Any, MetricState.Gauge]