Getting Started
This guide walks you through adding Choreo to your project and writing your first choreography.
Installation
Section titled “Installation”Choreo is built for Scala 3 and uses cats-effect for effectful computation.
Add the following dependencies:
def mvnDeps = Seq( mvn"me.romac::choreo:0.1.0", mvn"org.typelevel::cats-effect:3.6.3")libraryDependencies ++= Seq( "me.romac" %% "choreo" % "0.1.0", "org.typelevel" %% "cats-effect" % "3.6.3")Your First Choreography
Section titled “Your First Choreography”Let’s build a minimal two-party choreography where Alice sends a greeting to Bob, and Bob prints it.
Define Locations
Section titled “Define Locations”Locations are singleton String types that identify participants:
import choreo.*import choreo.backend.Backendimport cats.effect.IOimport cats.effect.IO.asyncForIOimport cats.syntax.all.*
val alice: "alice" = "alice"val bob: "bob" = "bob"Write the Choreography
Section titled “Write the Choreography”A choreography describes the global interaction between all participants using a for-comprehension:
def greeting: Choreo[IO, Unit] = for msgA <- alice.locally(IO.pure("Hello from Alice!")) msgB <- alice.send(msgA).to(bob) _ <- bob.locally(IO.println(s"Bob received: ${msgB.!}")) yield ()Here is what each step does:
alice.locally(...)runs a local computation at Alice, producing a value of typeString @@ "alice"— a string owned by Alice.alice.send(msgA).to(bob)sends Alice’s message to Bob, producing aString @@ "bob".bob.locally(...)runs a local computation at Bob. Insidelocally, Bob can unwrap his own values using the!operator.
Run the Choreography
Section titled “Run the Choreography”Create a backend and project the choreography for each participant:
def main: IO[Unit] = for backend <- Backend.local(List(alice, bob)) aliceTask = greeting.project(backend, alice) bobTask = greeting.project(backend, bob) _ <- (aliceTask, bobTask).parTupled yield ()Backend.local creates an in-process backend with per-channel message queues. The project method performs endpoint projection (EPP), transforming the global choreography into a network program for a specific location. Finally, parTupled runs both participants concurrently.
Running the Example
Section titled “Running the Example”If you have this code in your project:
./mill myproject.runOr, to try the built-in examples:
./mill examples.runMain choreo.examples.kv./mill examples.runMain choreo.examples.booksellerIf you have this code in your project:
sbt runOr, to try the built-in examples:
sbt "examples/runMain choreo.examples.kv"sbt "examples/runMain choreo.examples.bookseller"Next Steps
Section titled “Next Steps”- Core Concepts — learn about locations, communication, branching, and endpoint projection.
- Examples — see complete working examples.