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 full Orleans power 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 pure state -> reply handlers, and there is no 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.
Full Orleans parity, 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.
2,500+ Tests
2,500+ unit and integration tests on a dual-version Orleans CI matrix, including property-based verification with FsCheck and a 16-feature live 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 | 2,500+ unit + integration tests |
| Orleans support | 10.1.0 – 10.2.2, CI-tested at both ends of the range |
| Feature tour | 16 Orleans capabilities demonstrated live in examples/feature-tour |
| NuGet packages | 8 — core, runtime, abstractions, testing, event sourcing, codegen, 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.Templatesdotnet new orleans-fsharp -n MyAppcd MyAppdotnet build && dotnet testA working Orleans.FSharp solution with a counter grain, FsCheck property tests, and silo configuration — ready in under 2 minutes.
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.EventSourcing
Compatibility package for applications covered by the separate Legacy API documentation. Current event-sourced actors use journaledGrainFor from the core package.
Orleans.FSharp.Testing
TestHarness, WebTestHarness, MockGrainFactory, GrainArbitrary, and log capture utilities.
Orleans.FSharp.Analyzers
Compile-time safety checks (for example OF0001 for async { }) with explicit opt-out where needed.
Every major Orleans capability, wrapped in idiomatic F#:
onLifecycle hooksonStream / onBroadcast) that activate a functional grain on publishIAsyncEnumerable<'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