Skip to content

Event sourcing in any language: how Chronicle's gRPC contract works

Event sourcing libraries are usually tied to one language: the store, the client, and the programming model ship as a single package for a single ecosystem. Chronicle takes a different shape. It is an event-sourcing database and processing runtime with a first-class .NET SDK and additional TypeScript, Kotlin/Java (JVM), and Elixir clients — with a Python client coming soon — and the boundary between the server and every one of those clients is a wire contract, not a language binding.

This post walks through how that contract works: what the server exposes, how the shipped clients are layered on top of it, and what a new client for another language actually has to implement.

Chronicle uses a .NET/Orleans actor-based kernel behind gRPC/HTTP surfaces and supports multiple event stores, namespaces, and persistent event-store subscriptions with outbox/inbox sequences. The kernel is where the event-sourcing behavior lives; clients talk to it over the network.

The contract itself is a set of 22 canonical .proto files in the Chronicle repository, under Source/Kernel/Protobuf. Together they describe the full client-facing surface: event types and event sequences, event stores and namespaces, observation (reactors, reducers, and event-store subscriptions), projections and read models, jobs, constraints, compliance, identities, recommendations, and the host and client handshake itself.

Because the boundary is protobuf over gRPC, any language with a gRPC implementation can talk to it. There is nothing .NET-specific on the wire — the .NET SDK is a client of the same contract as everyone else.

Every client Chronicle has shipped follows the same layering, documented in the Building a Chronicle Client guide:

  1. The canonical .proto files — owned by the kernel, versioned with it.
  2. A generated contracts package per language — strongly-typed bindings generated from the protos and published as an ordinary package. It is regenerated by Chronicle’s own pipeline on every kernel release and treated as read-only.
  3. An idiomatic client — the hand-maintained package developers actually import. This is where the language’s own idioms live: decorators in TypeScript, annotations on the JVM, processes and supervision in Elixir, attributes in .NET. It depends on the contracts package; its users never have to.
  4. Optional convenience packages — hosting integrations such as ASP.NET Core or Spring Boot support, layered above the idiomatic client.

The result is that “event sourcing in language X” doesn’t mean porting a database. It means generating bindings from the same 22 contracts and writing the idiomatic layer that makes them feel native.

Hand-rolling a client means solving the same handful of plumbing problems every existing client has solved before it can do anything useful:

  • Typed bindings generated from the wire contract, kept in a separate contracts package rather than hand-edited.
  • Authentication — parsing the connection string’s authentication modes and exchanging credentials for a token, keeping it fresh.
  • Connection lifecycle — discovering servers, reconnecting when a connection drops.
  • Contract-version checking — rejecting a server whose contract has drifted instead of silently sending it garbage.

None of that is domain logic, and all of it is written down: the Building a Chronicle Client section of the documentation is the experience of building the TypeScript, Kotlin, and Elixir clients distilled into a checklist, with a page explaining the why behind each item.

Each shipped client has its own landing page with installation and a first taste of the API:

  • .NET — the first-class SDK, Cratis.Chronicle on NuGet.
  • TypeScript and Node.js@cratis/chronicle on npm.
  • Kotlin and Java (JVM)io.cratis:chronicle on Maven Central, including a Spring Boot starter.
  • Elixircratis_chronicle on Hex.
  • Python — coming soon: pre-alpha, no package published yet, and no commitment implied.

All of them are built on the same wire contract: the same 22 canonical .proto files, generated into a contracts package for each language, with an idiomatic client layered on top.

Chronicle is MIT licensed and free to use, and so is everything Cratis publishes today.