Overview
Conduit is a Scala 3 / ZIO 2 library for unidirectional state. Actions describe what happened. Handlers turn those into a new immutable model. Listeners react to slices that actually changed.
It cross-builds for JVM, Scala.js, and Scala Native. The docs site is JVM + a Scala.js client that remounts the live widgets; the library itself has no UI dependency.
libraryDependencies += "rocks.earlyeffect" %% "conduit" % "<version>"
Use %%% in a Scala.js or Native build. Pair with
ascent-conduit when the host is an ascent UI; that bridge
is optional and lives in ascent, not here.
The loop
Enqueue is cheap and asynchronous. Nothing is applied until run(). Follow-ups returned from a
handler are dispatched immediately (nested), then the loop continues. Click a node in the diagram
to highlight it.
Mermoid.diagram(loop)Mermoid.diagramInteractive(loop, initialWidth = 720)Four pieces
| Piece | Job |
|---|---|
| Model | Immutable case class, usually derives Optics |
| Action | enum X extends Action (alias for AppAction[Any, Nothing]) |
| Handler | Partial function from action to ActionResult on a lensed slice |
| Conduit | Queue + Ref + dispatch loop + listeners |
Read Getting started for a clickable counter, then Mental model
for how FastEq, follow-ups, and run vs run(false) fit together.