zio / zio-nio   2.0.1

Apache License 2.0 Website GitHub

A small, unopinionated ZIO interface to NIO.

Scala versions: 3.x 2.13 2.12 2.11


ZIO NIO is a ZIO wrapper on Java NIO, an opinionated interface with deep ZIO integration that provides type and resource safety.

Development CI Badge Sonatype Releases Sonatype Snapshots javadoc ZIO NIO


Java NIO is unsafe, and can surprise you a lot with e.g. hiding the actual error in IO operation and giving you only true/false values when IO was successful/not successful. ZIO NIO on the other hand embraces the full power of ZIO effects, environment, error and resource management to provide type-safe, performant, purely-functional, low-level, and unopinionated wrapping of Java NIO functionality.

In Java, there are two packages for I/O operations:

  1. Java IO (java.io)

    • Standard Java IO API
    • Introduced since Java 1.0
    • Stream-based API
    • Blocking I/O operation
  2. Java NIO (java.nio)

    • Introduced since Java 1.4
    • NIO means New IO, an alternative to the standard Java IO API
    • It can operate in a non-blocking mode if possible
    • Buffer-based API

The Java NIO is an alternative to the Java IO API. Because it supports non-blocking IO, it can be more performant in concurrent environments like web services.

Main Abstractions

  • Using Blocking APIs — How to deal with NIO APIs that block the calling thread
  • File Channel — For processing files that are available locally. For every operation a new fiber is started to perform the operation.
  • Socket Channel — Provides an API for remote communication with InetSockets.
  • Resource Management - Avoiding resource leaks
  • Character Sets - For encoding or decoding character data.


ZIO NIO comes in two flavors:

  • zio.nio.core — a small and unopionanted ZIO interface to NIO that just wraps NIO API in ZIO effects,
  • zio.nio — an opinionated interface with deeper ZIO integration that provides more type and resource safety.

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

libraryDependencies += "dev.zio" %% "zio-nio-core" % "2.0.0"
libraryDependencies += "dev.zio" %% "zio-nio"      % "2.0.0" 


Let's try writing a simple server using zio-nio module:

import zio._
import zio.console._
import zio.nio.channels._
import zio.nio.core._
import zio.stream._

object ZIONIOServerExample extends zio.App {
  val myApp =
      .use(socket =>
        for {
          addr <- InetSocketAddress.hostName("localhost", 8080)
          _ <- socket.bindTo(addr)
          _ <- putStrLn(s"Waiting for incoming connections on $addr endpoint").orDie
          _ <- ZStream
            .mapMPar(16) {
              _.use { case (closeConn, channel) =>
                for {
                  _ <- putStrLn("Received connection").orDie
                  data <- ZStream
                    .run(Sink.foldLeft("")(_ + _))
                  _ <- closeConn
                  _ <- putStrLn(s"Request Received:\n${data.mkString}").orDie
                } yield ()
        } yield ()
  override def run(args: List[String]): URIO[zio.ZEnv, ExitCode] =

Now we can send our requests to the server using curl command:

curl -X POST localhost:8080 -d "Hello, ZIO NIO!"




Learn more on the ZIO NIO homepage!


For the general guidelines, see ZIO contributor's guide.

Code of Conduct

See the Code of Conduct


Come chat with us on Badge-Discord.