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.
One kernel, one wire contract
Section titled “One kernel, one wire contract”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.
How every client is layered
Section titled “How every client is layered”Every client Chronicle has shipped follows the same layering, documented in the Building a Chronicle Client guide:
- The canonical
.protofiles — owned by the kernel, versioned with it. - 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.
- 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.
- 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.
What a new client implements
Section titled “What a new client implements”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.
Chronicle in your language today
Section titled “Chronicle in your language today”Each shipped client has its own landing page with installation and a first taste of the API:
- .NET — the first-class SDK,
Cratis.Chronicleon NuGet. - TypeScript and Node.js —
@cratis/chronicleon npm. - Kotlin and Java (JVM) —
io.cratis:chronicleon Maven Central, including a Spring Boot starter. - Elixir —
cratis_chronicleon 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.
Free and open source
Section titled “Free and open source”Chronicle is MIT licensed and free to use, and so is everything Cratis publishes today.
Where to go next
Section titled “Where to go next”- Get started with Chronicle — your first event-sourced application.
- Building a Chronicle Client — the full guide and checklist for bringing Chronicle to a new language.
- Chronicle architecture — how the kernel is put together.
- Chronicle on GitHub — the kernel, the contracts, and the .NET SDK.
- Community and help — where to ask questions and follow along.