The Go client for Cratis Chronicle, the event store in Cratis Platform. You can adopt Chronicle without the other Platform components. Register typed events, select a store and namespace, and append with explicit concurrency protection and complete outcomes.
v0.x. The source includes appends, reads, observers, projections and normal-session recovery, with feature-specific restrictions. Start with the single capability and limits summary, then the detailed parity and limitations. Source API presence is not production readiness or a compatibility guarantee for a selected release.
Requires Go 1.26 or later. v0.x tags exist, including v0.11.1. Consult the release policy before selecting a version; current main source and a tagged module can differ. The install command asks Go to resolve the latest module version:
go get github.com/cratis/chronicle.go@latestContracts are pinned to Chronicle 19.150.1; real-kernel tests use 19.150.1-development. The pin is not a supported kernel range: decision reads require this exact version (see the capability summary). Generated contracts are public packages in this same module, with no .NET or sibling checkout needed.
Start the development kernel and wait for https://localhost:35000/health to report Healthy. Health establishes process health, not feature compatibility; read the getting-started environment notes before relying on a feature:
docker run --rm --name chronicle-go -p 127.0.0.1:35000:35000 cratis/chronicle:19.150.1-developmentThe maintained program is available as go run ./examples/getting-started in a checkout against that kernel. It owns a normal client, including its keep-alive worker; it is not a runnable skipped-session job example. Read short-lived clients and process ownership before choosing WithSkipKeepAlive:
package main
import (
"context"
"errors"
"fmt"
"log"
"time"
chronicle "github.com/cratis/chronicle.go"
"github.com/cratis/chronicle.go/events"
)
type CustomerRegistered struct {
Name string `json:"name"`
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := appendCustomer(ctx); err != nil {
log.Fatal(err)
}
}
func appendCustomer(ctx context.Context) (err error) {
registry := chronicle.NewRegistry()
if _, err = chronicle.RegisterEvent[CustomerRegistered](registry,
events.WithID("customer-registered")); err != nil {
return err
}
client, err := chronicle.NewClient(chronicle.WithDevelopmentDefaults(),
chronicle.WithRegistry(registry))
if err != nil {
return err
}
defer func() { err = errors.Join(err, client.Close()) }()
store, err := client.EventStore(ctx, "customers")
if err != nil {
return err
}
result, err := store.EventLog().Append(ctx, "customer-42", CustomerRegistered{Name: "Ada"})
if err != nil {
return err
}
if err = result.Err(); err != nil {
return err
}
fmt.Printf("Appended event at position %d\n", *result.Position)
return nil
}WithDevelopmentDefaults explicitly permits the kernel's self-signed certificate. Production TLS validates by default: configure real roots and credentials. An append transport error may hide a committed event; never blindly retry. Default optimistic concurrency leaves empty history unchecked; use NoMatchingEvent when first append must be protected.
- Getting started
- Connecting and lifecycle
- Webhook authentication evidence and limits
- Event types
- Declared Int32 enum codecs
- Appending and concurrency
- Atomic batches
- Reading events and history
- Contributing and required checks
export GOWORK=off
go build ./...
go vet ./...
go test -race -count=1 -timeout=3m ./...
golangci-lint run
go generate ./...
python3 scripts/generate-contracts.py --checkDiscord (questions and help) · Documentation · Cratis · Cratis repositories · Private vulnerability reporting · MIT license