Back to Skills

eio

verified

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 GitHub

Marketplace

ocaml-claude-marketplace

avsm/ocaml-claude-marketplace

Plugin

ocaml-dev

development

Repository

avsm/ocaml-claude-marketplace
15stars

plugins/ocaml-dev/skills/eio/SKILL.md

Last Verified

January 20, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/avsm/ocaml-claude-marketplace/blob/main/plugins/ocaml-dev/skills/eio/SKILL.md -a claude-code --skill eio

Installation paths:

Claude
.claude/skills/eio/
Powered by add-skill CLI

Instructions

# 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

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
9728 chars