Orleans.FSharp
Core developer surface: grainContract, grainFor, journaledGrainFor, observers, streaming, logging, reminders, timers, and serialization.
Microsoft Orleans is one of the strongest virtual actor runtimes on .NET. But in raw C# style, F# teams often end up with mutable state classes, attribute noise, and repetitive infrastructure code.
Orleans.FSharp keeps Orleans underneath while giving you a functional-first authoring model: a grain’s public surface is a plain F# record of functions, its behavior is a set of explicit state transitions, and there is no application interface, attribute, or code-generation bridge to write.
type ICounterGrain = inherit IGrainWithStringKey abstract Increment: unit -> Task<int> abstract Value: unit -> Task<int>
// ...plus a C# shim project in the solution, because Orleans'// proxy source generator does not run on F# projects.type CounterGrain() = inherit Grain() let mutable count = 0
interface ICounterGrain with member _.Increment() = count <- count + 1 Task.FromResult count
member _.Value() = Task.FromResult counttype CounterApi = { increment: unit -> Task<int> value: unit -> Task<int> }
let counterContract = contract<string, CounterApi> { grainType "counter" version 1 stringKey readOnly (_.value) }
let counter = grainFor counterContract { defaultState (fun () -> 0) handle (_.increment) (fun _ctx n () -> task { return n + 1, n + 1 }) handleQuery (_.value) (fun _ctx n () -> task { return n }) }And the call site is the record itself — no proxy interface, no cast:
let api = FunctionalGrain.ref counterContract factory "my-counter"let! n = api.increment ()Same two operations, same reply types — but state transitions are explicit values, the compiler checks every handler against the record’s field types, and sealing the definition verifies that each operation has exactly one handler. No interface, no shim project, no proxy generation.
Functional grain runtime
The current authoring model: API record contracts, explicit key codecs, immutable state, and a fixed wire protocol with precompiled proxies — no C# CodeGen interfaces anywhere.
Orleans features, functionally
Distributed ACID transactions, event sourcing over Orleans’ own log-consistency providers, implicit stream subscriptions, IAsyncEnumerable streaming replies, reentrancy policies, and version-tolerant contracts — all as contract or definition operations.
siloConfig { } CE
Configure clustering, storage, streaming, TLS, health checks, and runtime services without extension-method boilerplate.
Orleans Dashboard
Run Microsoft’s Dashboard with functional actors, including a verified example and the exact actor names shown in its activation table.
FSharpBinaryCodec
Serialize F# DUs, records, options, lists, and maps with minimal ceremony and predictable behavior for mixed cluster scenarios.
Compatibility tested
Unit and integration suites on both ends of the supported Orleans range, including separate-process rolling upgrades, durable fixtures, FsCheck, and a live feature tour.
Callable from C#
A typed facade over any functional contract: ordinary awaited calls and await foreach over streaming operations, generated at runtime with no build step.
| Metric | Value |
|---|---|
| Test suite | Unit, integration, provider, rolling-update, and persisted-fixture coverage |
| Orleans support | 10.1.0 – 10.3.1, CI-tested at both ends of the range |
| Feature tour | 16 Orleans capabilities demonstrated live in examples/feature-tour |
| Production package set | 6 — core, runtime, abstractions, testing, analyzers, templates |
| License | MIT |
| Dispatch overhead | under 5% versus calling the handler function directly, measured over 1,000,000 iterations |
dotnet new install Orleans.FSharp.Templates@5.0.1dotnet new orleans-fsharp -n MyAppcd MyAppdotnet build && dotnet testA working Orleans.FSharp 5.0.1 solution with a counter grain, FsCheck property tests, and silo configuration. The packaged template references the matching 5.0.1 packages.
Orleans.FSharp
Core developer surface: grainContract, grainFor, journaledGrainFor, observers, streaming, logging, reminders, timers, and serialization.
Orleans.FSharp.Runtime
Hosting and client runtime: AddFunctionalGrain registration, siloConfig {} and clientConfig {} builders for production setup.
Orleans.FSharp.Abstractions
The fixed functional transport: request envelopes, protocol tokens, and precompiled Orleans proxies — reference it once, generate nothing.
Orleans.FSharp.Testing
TestHarness, WebTestHarness, MockGrainFactory, GrainArbitrary, and log capture utilities.
Orleans.FSharp.Analyzers
F# safety checks (for example OF0001 for async { }) run through the fsharp-analyzers CLI, with explicit opt-out where needed.
Orleans.FSharp.Templates
The current functional solution template, with exact references to the matching release packages.
The current wrapped and composed surface includes:
onLifecycle hooksonStream / onBroadcast) and Orleans 10.3+ stateless-worker competing consumers for onStreamIAsyncEnumerable<'T>, riding Orleans’ own extension — await foreach-able from C#reentrant and per-request mayInterleave as contract operations; statelessWorker as a definition operationplacement (PreferLocal, ActivationCountBased, ResourceOptimized, Random) as a definition operationjournaledGrainFor — pure apply fold over Orleans’ LogStorage/StateStorage log-consistency providers, with typed custom snapshotstransactional contract operations and transactionalStateFrom facetsacceptsVersions and per-operation sinceVersion