cats-effect-io
Cats Effect IO (Scala)
Quick start
- Treat every side effect as an effect value: return
IO[A],SyncIO[A], orF[A]withF[_]: Sync/Async/Temporalas needed. - Wrap Java blocking calls with
IO.blockingorIO.interruptible(orSync[F].blocking/interruptible). - Use
Resourceto acquire/release resources andIOAppfor program entry points. - Prefer structured concurrency (
parTraverse,parMapN,background,Supervisor) over manual fiber management. - Do not use
unsafeRun*(unsafeRunSync,unsafeRunAndForget, etc.) in app code or tests; for interop with non-Cats-Effect callback APIs, useDispatcher. - Read
references/cats-effect-io.mdfor concepts, recipes, and FAQ guidance. - For deeper
Resourceguidance, use thecats-effect-resourceskill (install:npx skills add https://github.com/alexandru/skills --skill cats-effect-resource).
Workflow
- Classify side effects and choose the effect type:
IOdirectly or polymorphicF[_]with the smallest required Cats Effect typeclass (Sync,Async,Temporal,Concurrent). - Wrap side-effectful code using
IO(...),IO.blocking,IO.interruptible, orIO.async(or theirSync/Asyncequivalents). - Manage resources with
Resourceorbracketand keep acquisition/release inside effects. - Compose effects with
flatMap/for-comprehensions and collection combinators (traverse,parTraverse). - Use concurrency primitives (
Ref,Deferred,Queue,Semaphore,Supervisor) and structured concurrency to avoid fiber leaks. - Keep effect execution at boundaries (
IOApp, framework runtime); for callback-style interop, bridge withDispatcher.
Side-effect rules (apply to IO, SyncIO, and to F[_]: Sync/Async)
- All side-effectful functions must return results wrapped in
IO(orF[_]with Cats Effect typeclasses). - Side-effects include all non-determinism (call sites are not referentially transparent):
- Any I/O (files, sockets, console, databases).
Instant.now(),Random.nextInt().- Any read from shared mutable state (the read itself is the side effect).
- Returning mutable data structures (for example,
Array[Int]).
Blocking I/O rules
- Java blocking methods must be wrapped in
IO.blockingorIO.interruptible(orSync[F].blocking/interruptible) so they run on the blocking pool. - Prefer
IO.interruptiblefor methods that may throwInterruptedExceptionorIOException, but not for resource disposal. - Use
IO.blockingfor cleanup/disposal (Closeable#close,AutoCloseable#close).
Output expectations
- Make side effects explicit in signatures (
IO/SyncIOorF[_]: Sync/Async); the guidance here applies equally to concreteIOand polymorphicF[_]. - Use the smallest typeclass constraint that supports the needed operations.
- Keep effects as values; do not execute effects in constructors or top-level vals.
Execution and test rules
unsafeRun*is forbidden in production and test code, includingimport cats.effect.unsafe.implicits.global.- If interop requires running effects from non-Cats-Effect callbacks, use
Dispatcher. - Prefer effect-native test styles (return
IO[Assertion]/F[Assertion]) instead of manually running effects. - Avoid
IO.sleep/Thread.sleepin unit tests unless using virtual time withTestControl.
References
- Load
references/cats-effect-io.mdfor documentation summary and patterns. - For concrete samples, read
references/cats-effect-io.md. - Use the
cats-effect-resourceskill for Resource-specific workflows and patterns (install:npx skills add https://github.com/alexandru/skills --skill cats-effect-resource).
More from alexandru/skills
cats-effect-resource
Scala resource lifecycle management with Cats Effect `Resource` and `IO`. Use when defining safe acquisition/release, composing resources (including parallel acquisition), or designing resource-safe APIs and cancellation behavior for files, streams, pools, clients, and background fibers.
36cats-mtl-typed-errors
Scala typed errors with Cats MTL Raise/Handle and allow/rescue. Use for designing custom domain error types without EitherT, while keeping Cats Effect and ecosystem composition. Covers Scala 2/3 syntax and IO-only or F[_] usage.
23akka-streams
Scala reactive streaming with Akka Streams and Pekko Streams. Use for dataflow and reactive programming patterns, testing stream components, and understanding when NOT to use streams (prefer plain functions for transformations and I/O).
20arrow-typed-errors
Kotlin + Arrow typed error handling using Raise DSL and wrapper types (Either/Option/Ior/Result/nullable), including validation with accumulation, interop with exceptions, and custom error wrappers. Use for designing or refactoring error modeling, converting exception-based flows, building smart constructors, accumulating validation errors, or integrating Outcome/Progress-style wrappers with Arrow.
16kotlin-java-library
Kotlin design for Java libraries and Java consumers. Use when building Kotlin code intended for Java callers, aligning with Java interop, JVM annotations, records, and backward/binary compatibility rules.
14jspecify-nullness
JSpecify nullness annotations for Java APIs and tooling. Use when adopting or migrating JSpecify annotations, designing null-safe Java signatures and generics, or interpreting tool conformance and Kotlin interop.
13