# Zio Reference

> Use when writing ZIO Scala code — implementing services with ZLayer, handling typed errors vs defects, choosing concurrency primitives (Ref, Queue, Hub, STM, Semaphore), avoiding anti-patterns like blocking on ZIO threads, unsafe resource handling with ensuring, or overusing Task for business logic

- **Type:** Skill
- **Install:** `agentstack add skill-linux-root-scala-zio-skills-zio-reference`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [linux-root](https://agentstack.voostack.com/s/linux-root)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [linux-root](https://github.com/linux-root)
- **Source:** https://github.com/linux-root/scala-zio-skills/tree/main/skills/zio-reference

## Install

```sh
agentstack add skill-linux-root-scala-zio-skills-zio-reference
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# ZIO Coding Reference

You are an expert Scala/ZIO developer. Follow these rules strictly when generating ZIO code.

## Core Concepts

- **ZIO[R, E, A]**: Immutable effect description. `R` = environment (contravariant), `E` = error (covariant), `A` = success (covariant). Effects are descriptions, not running computations.
- **Fibers**: Lightweight virtual threads managed by ZIO runtime. Millions can run concurrently. Fork starts one, join awaits it.
- **ZLayer**: Recipe for constructing services from dependencies with effectful init/finalize. Automates dependency graph wiring.
- **Scope**: Resource lifetime manager. Finalizers run on success, failure, or interruption.
- **Typed Errors vs Defects**: `E` channel = expected domain failures (compiler-checked). Defects = unexpected bugs captured in `Cause`, not in `E`.

> Deep dive: references/core-concepts.md

## Coding Rules

### Error Handling
> Deep dive: references/error-handling-deep-dive.md

- Model domain errors as sealed trait ADTs: `sealed trait UserError; case class NotFound(id: UUID) extends UserError`
- Use `ZIO.fail(NotFound(id))` not `ZIO.fail(new Exception("not found"))`
- Use `orDie` to shift `Throwable` to defect channel when unrecoverable: `ZIO.attempt(expr).orDie`
- Use `refineToOrDie[SpecificError]` to keep one error type, defect the rest
- Never swallow defects: `effect.tapDefect(c => ZIO.logErrorCause("Unexpected", c))` not `effect.catchAllDefect(_ => ZIO.unit)`
- Use `mapError` to unify error hierarchies across layers
- Use `catchAll` for recovery, `foldZIO` for transforming both paths
- Low-level: broad errors (`IOException`). High-level: refined domain ADTs or defects.
- Use `Either` only when errors are unrelated and you want to avoid widening `E` to `Any`

### Composition
- For-comprehensions for sequential composition:
  ```scala
  for { user ` (zipRight) / ` runTask
  ```

### Dependencies (Service Pattern)
- Trait defines interface (methods return `IO[E, A]` with `R = Any`)
- Case class implements trait, receives dependencies via constructor
- Companion object provides `ZLayer`
```scala
trait Greeter { def sayHello(name: String): UIO[Unit] }

case class GreeterLive(console: Console) extends Greeter {
  def sayHello(name: String): UIO[Unit] = console.printLine(s"Hello, $name!").orDie
}

object Greeter {
  val layer: URLayer[Console, Greeter] = ZLayer.derive[GreeterLive]
}
```

### Resources
- Always use `ZIO.acquireRelease` or `ZIO.acquireReleaseWith`, never `ensuring` for resource cleanup
- Use `ZIO.scoped` for narrowest possible resource lifetime:
  ```scala
  ZIO.scoped { ZIO.acquireRelease(open)(r => ZIO.succeed(r.close())).flatMap(use) }
  ```

### Concurrency
> Deep dive: references/concurrency-and-fiber.md

- Prefer `foreachPar`, `zipPar`, `race` over manual `fork`/`join`
- Always `join` or `interrupt` any manually forked fiber
- Use `ZIO.attemptBlocking` or `ZIO.attemptBlockingIO` for blocking I/O, never `ZIO.attempt`
- Use `ZIO.uninterruptibleMask(restore => setup *> restore(task) *> cleanup)` for custom operators
- Use `Ref` for single atomic state, `STM`/`TRef` for multi-variable transactional updates
- Don't wrap monolithic loops in `ZIO.succeed` — runtime can't interrupt inside them

## Anti-Patterns (Never Do These)
> Deep dive: references/anti-patterns.md

| Anti-Pattern | Correct |
|---|---|
| `Task[A]` for business logic | `IO[DomainError, A]` with sealed trait ADT |
| `val f = api(); ZIO.fromFuture(_ => f)` | `ZIO.fromFuture(ec => api()(ec))` |
| `trait Svc { def get: ZIO[Database, E, A] }` | `case class LiveSvc(db: Database) extends Svc { def get: IO[E, A] }` |
| `acquire.flatMap(r => use(r).ensuring(release(r)))` | `ZIO.acquireReleaseWith(acquire)(release)(use)` |
| `ZIO.attempt(blockingIOCall())` | `ZIO.attemptBlockingIO(blockingIOCall())` |
| `effect.catchAllDefect(_ => ZIO.unit)` | `effect.tapDefect(c => ZIO.logErrorCause("err", c))` |
| `effect.fork *> ZIO.unit` | `effect.fork.flatMap(_.join)` or use structured concurrency |
| `ZIO.succeed(while(true) { ... })` | Recursive ZIO effect or `.forever` |
| `object Svc { def method(a: A): ZIO[Svc, E, B] = ZIO.serviceWithZIO(_.method(a)) }` | Call `ZIO.serviceWithZIO[Svc](_.method(a))` directly at call sites |

## Decision Guide: Which Abstraction?
> Deep dive: references/when-to-use-what.md

| Need | Use | Not |
|---|---|---|
| Service wiring + lifecycle | `ZLayer` | Manual instance passing |
| Single shared mutable state | `Ref` | `var`, `AtomicReference` |
| Multi-variable atomic updates | `STM` / `TRef` | Multiple `Ref` updates |
| Work distribution (one consumer per item) | `Queue` | `Hub` |
| Broadcast (all consumers get every item) | `Hub` | `Queue` |
| Retry with backoff / repeat on schedule | `Schedule` | Manual recursion |
| One-shot synchronization between fibers | `Promise` | `Queue`, `Ref` |
| Limit concurrent access | `Semaphore` | Manual counting |
| Incremental / infinite data processing | `ZStream` | `ZIO` returning `List` |
| Resource with finalization | `Scope` + `acquireRelease` | `ensuring` |
| Low-level fiber control | `Fiber` + `fork` | Default; prefer `foreachPar`/`zipPar` |

## Key Patterns
> More patterns: references/minimal-working-patterns.md | references/idioms.md

### Service Pattern (Repository variant)
```scala
trait UserRepo { def findById(id: UUID): IO[RepoError, Option[User]] }

case class PostgresUserRepo(ds: DataSource) extends UserRepo {
  def findById(id: UUID): IO[RepoError, Option[User]] =
    ZIO.attemptBlocking(query(ds, id)).mapError(DbError(_))
}

object UserRepo {
  val layer: ZLayer[DataSource, Nothing, UserRepo] = ZLayer.derive[PostgresUserRepo]
}
```

### Background Worker
```scala
def startWorker(queue: Queue[Job]): ZIO[Any, Nothing, Fiber.Runtime[Nothing, Nothing]] =
  queue.take.flatMap(job => process(job).ignoreLogged).forever.forkDaemon
```

### Retry with Backoff
```scala
val policy = Schedule.exponential(1.second) && Schedule.recurs(5)
ZIO.attempt(unstableCall()).retry(policy)
```

### Parallel with Limit
```scala
ZIO.foreachPar(urls)(fetch).withParallelism(10)
```

### HTTP Route (ZIO HTTP)
```scala
val route: Route[UserRepo, Nothing] =
  Method.GET / "users" / uuid("id") -> handler { (id: UUID, req: Request) =>
    ZIO.serviceWithZIO[UserRepo](_.findById(id)).map {
      case Some(user) => Response.json(user.toJson)
      case None       => Response.notFound
    }.orDie
  }
```

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [linux-root](https://github.com/linux-root)
- **Source:** [linux-root/scala-zio-skills](https://github.com/linux-root/scala-zio-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-linux-root-scala-zio-skills-zio-reference
- Seller: https://agentstack.voostack.com/s/linux-root
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
