Eio concurrency patterns for OCaml applications. Use when Claude needs to: (1) Write concurrent OCaml code with Eio, (2) Handle network operations with cohttp-eio, (3) Manage resource lifecycles with switches, (4) Implement rate limiting or synchronization, (5) Create parallel operations with fibers, (6) Test async code with Eio_mock, (7) Integrate with bytesrw for streaming, or any other Eio-based concurrency tasks
View on GitHubavsm/ocaml-claude-marketplace
ocaml-dev
January 20, 2026
Select agents to install to:
npx add-skill https://github.com/avsm/ocaml-claude-marketplace/blob/main/plugins/ocaml-dev/skills/eio/SKILL.md -a claude-code --skill eioInstallation paths:
.claude/skills/eio/# Eio Concurrency
## Core Concepts
### Why Eio
Eio is an effects-based IO library for OCaml 5. Advantages over Lwt/Async:
- **Direct-style code**: No monads, concurrent code looks like sequential code
- **Performance**: Real stacks, no heap allocations to simulate continuations
- **Better backtraces**: Exceptions show proper call traces
- **Platform optimization**: Generic API with optimized backends (Linux io_uring, POSIX, Windows)
### Capability-Based Design
Pass capabilities explicitly instead of using global resources:
```ocaml
type t = {
net : _ Eio.Net.t;
clock : _ Eio.Time.clock;
fs : _ Eio.Path.t;
}
(* Function signature reveals what resources it needs *)
val connect : net:_ Eio.Net.t -> host:string -> connection
```
**Do**: Pass `net`, `clock`, `fs` explicitly—makes dependencies clear and testable.
**Don't**: Use global modules like `Unix.gettimeofday` or access ambient resources.
### Structured Concurrency with Switches
`Eio.Switch.run` manages resource and fiber lifecycles:
```ocaml
Eio.Switch.run @@ fun sw ->
let conn = connect ~sw server in
(* conn automatically closed when sw exits *)
process conn
```
**Do**: Create switches in the smallest possible scope.
**Don't**: Take a switch argument if you could create one internally.
### Fibers
Lightweight concurrent units running on a single core:
```ocaml
(* Run two operations concurrently *)
Eio.Fiber.both
(fun () -> download file1)
(fun () -> download file2)
(* Only one fiber executes at a time until one performs an effect *)
```
### Cancellation
Cancellation contexts form a tree. Uncaught exceptions propagate upward, cancelling siblings:
```ocaml
(* If one branch fails, the other gets Cancelled *)
Eio.Fiber.both
(fun () -> may_fail ())
(fun () -> other_work ()) (* receives Cancelled if may_fail raises *)
```
Use `Cancel.protect` for operations that must complete:
```ocaml
Eio.Cancel.protect @@ fun () ->
(* This won't be cancelled even if parent is *)
flush_a