synapse

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 1, 2026 License: Apache-2.0 Imports: 0 Imported by: 0

README

synapse

CI

A small Go event sourcing and CQRS toolkit. Composable primitives — aggregates, events, repositories, projections — with zero third-party deps in the core and pluggable backends for events, snapshots, and projection checkpoints.

Status

Pre-1.0. The public surface is still moving; expect minor breaking changes between tagged versions. The persistent stack (SQLite events + snapshots + checkpoints, one file) is shaping up production-ready but has not yet seen production traffic.

Install

go get github.com/ianunruh/synapse

Requires Go 1.26 or newer.

Quick look

package main

import (
    "context"

    jsoncodec "github.com/ianunruh/synapse/codec/json"
    "github.com/ianunruh/synapse/es"
    "github.com/ianunruh/synapse/eventstore/memory"
)

// Define an aggregate by embedding *es.AggregateBase.

type Counter struct {
    *es.AggregateBase
    Value int
}

func NewCounter(id es.StreamID) *Counter {
    return &Counter{AggregateBase: es.NewAggregateBase(id)}
}

type CounterIncremented struct {
    By int `json:"by"`
}

func (c *Counter) Apply(env es.Envelope) {
    if inc, ok := env.Payload.(CounterIncremented); ok {
        c.Value += inc.By
    }
}

func (c *Counter) Increment(by int) {
    c.Record("counter.incremented", CounterIncremented{By: by}, c.Apply)
}

func main() {
    ctx := context.Background()

    reg := es.NewRegistry()
    es.Register(reg, "counter.incremented", jsoncodec.For[CounterIncremented]())

    repo := es.NewRepository(memory.New(), reg, NewCounter)

    c := NewCounter("counter/hits")
    c.Increment(2)
    c.Increment(3)
    _ = repo.Save(ctx, c)

    loaded, _ := repo.Load(ctx, "counter/hits")
    _ = loaded.Value // == 5
}

A full walkthrough is in docs/getting-started.md. Runnable examples live under examples/.

Documentation

Packages

The repo is a Go workspace. Core interfaces live in es; backends and contract suites are sibling packages — or sibling modules when they pull in third-party deps.

Package Module What it is
es root Aggregate, Repository, Event, Envelope, Snapshotter, Projection, etc.
es/middleware root Built-in repository middleware: PerAggregateLocking, Retry
es/projection root Runner for read-model projections (type filters, batched checkpoints)
es/commandbus root Transport-facing CommandBus + middleware (Logging, Recover, Timeout)
codec/json root JSON event/snapshot codec
codec/proto sibling Protobuf event/snapshot codec
codec/codectest root Codec contract test suite
idgen root UUIDv7 identifier generator
eventstore/memory root In-memory event store
eventstore/postgres sibling Postgres event store (pgxpool, shared LISTEN/NOTIFY)
eventstore/sqlite sibling SQLite event store
eventstore/eventstoretest root Backend contract test suite
snapshotstore/memory root In-memory snapshot store
snapshotstore/postgres sibling Postgres snapshot store
snapshotstore/sqlite sibling SQLite snapshot store
snapshotstore/snapshotstoretest root Backend contract test suite
checkpointstore/memory root In-memory checkpoint store
checkpointstore/postgres sibling Postgres checkpoint store
checkpointstore/sqlite sibling SQLite checkpoint store
checkpointstore/checkpointstoretest root Backend contract test suite
pgtest sibling Postgres testing harness (testcontainers-go)
examples/counter root In-memory event sourcing walkthrough
examples/order root Multi-stage aggregate with command validation
examples/projection root Projection runner walkthrough
examples/persistent sibling SQLite-backed end-to-end demo
examples/http-service root CommandBus driven by net/http, live projection

Sibling modules each have their own go.mod. A go.work file at the repo root ties them together for local development. The root module has zero third-party deps; the SQLite backends transitively pull in modernc.org/sqlite (pure Go, no CGo).

Design principles

Recorded as Architecture Decision Records (starting at ADR-0001):

  • Go 1.26 toolchain, language features and stdlib used to current capability.
  • Zero third-party deps in the root module. Backends that need them live as sibling Go modules.
  • Modernization-clean. gopls modernize ./... exits 0 in every module.
  • Serialization-agnostic core. Codecs are registered per event type; the es package never imports a specific codec.
  • Type safety and performance are co-equal goals. Where they point the same direction (most cases), take both. Where they conflict, prefer the perf-friendly option in hot paths and document the trade-off.
  • Admin RPCs and a web UI, when they exist, will be optional sibling subpackages users opt into.

License

Apache 2.0. See LICENSE.

Documentation

Overview

Package synapse is a toolkit for building event-sourced systems in Go.

The library is organized as a set of small subpackages so applications import only what they need. This package itself is doc-only — there is nothing to import from it.

Core (root module, no third-party deps):

Codecs (per-event-type, opt-in):

  • github.com/ianunruh/synapse/codec/json — encoding/json adapter, root module, stdlib only.
  • github.com/ianunruh/synapse/codec/proto — google.golang.org/protobuf adapter, sibling module so the protobuf dep stays out of the core.

Event, snapshot, and checkpoint store backends:

Shared infrastructure:

Architectural decisions are recorded under docs/adr/. Read the relevant ADR before relitigating a decision.

Directories

Path Synopsis
admin module
checkpointstore
checkpointstorebench
Package checkpointstorebench provides a benchmark harness any implementation of es.CheckpointStore can run.
Package checkpointstorebench provides a benchmark harness any implementation of es.CheckpointStore can run.
checkpointstoretest
Package checkpointstoretest provides a contract test suite that any implementation of es.CheckpointStore can run to verify the documented behavior.
Package checkpointstoretest provides a contract test suite that any implementation of es.CheckpointStore can run to verify the documented behavior.
memory
Package memory provides an in-memory es.CheckpointStore suitable for tests, examples, and local development.
Package memory provides an in-memory es.CheckpointStore suitable for tests, examples, and local development.
postgres module
sqlite module
codec
codectest
Package codectest provides a shared contract suite for es.TypedCodec implementations, mirroring the role eventstoretest plays for event stores (ADR-0018).
Package codectest provides a shared contract suite for es.TypedCodec implementations, mirroring the role eventstoretest plays for event stores (ADR-0018).
json
Package json provides an es.TypedCodec backed by the standard library's encoding/json package.
Package json provides an es.TypedCodec backed by the standard library's encoding/json package.
proto module
Package crypto wires synapse to per-subject crypto-shredding.
Package crypto wires synapse to per-subject crypto-shredding.
keystoretest
Package keystoretest provides a contract test suite that any implementation of crypto.KeyStore can run to verify the documented behavior.
Package keystoretest provides a contract test suite that any implementation of crypto.KeyStore can run to verify the documented behavior.
deadletterstore
postgres module
sqlite module
es
Package es provides event sourcing and CQRS primitives that can be composed into application-specific aggregates, command handlers, and read models.
Package es provides event sourcing and CQRS primitives that can be composed into application-specific aggregates, command handlers, and read models.
commandbus
Package commandbus routes named, byte-encoded commands to the typed es.Handler registered for them, so HTTP and gRPC transports can dispatch commands without writing a per-route adapter by hand.
Package commandbus routes named, byte-encoded commands to the typed es.Handler registered for them, so HTTP and gRPC transports can dispatch commands without writing a per-route adapter by hand.
middleware
Package middleware provides built-in es.Middleware implementations for common cross-cutting concerns around command execution: per-aggregate locking, retry on transient errors, and so on.
Package middleware provides built-in es.Middleware implementations for common cross-cutting concerns around command execution: per-aggregate locking, retry on transient errors, and so on.
process
Package process provides a thin wrapper for the process-manager pattern: an aggregate that consumes events from one or more streams and emits commands to drive a multi-step workflow.
Package process provides a thin wrapper for the process-manager pattern: an aggregate that consumes events from one or more streams and emits commands to drive a multi-step workflow.
projection
Package projection drives consumers of the event log via a Runner that subscribes to a es.EventStore, decodes events through a codec es.Registry, invokes a es.Projection, and (optionally) checkpoints progress to a es.CheckpointStore so consumers resume across restarts.
Package projection drives consumers of the event log via a Runner that subscribes to a es.EventStore, decodes events through a codec es.Registry, invokes a es.Projection, and (optionally) checkpoints progress to a es.CheckpointStore so consumers resume across restarts.
eventstore
eventstorebench
Package eventstorebench provides a benchmark harness any implementation of es.EventStore can run to measure append and load performance under standardized workloads.
Package eventstorebench provides a benchmark harness any implementation of es.EventStore can run to measure append and load performance under standardized workloads.
eventstoretest
Package eventstoretest provides a contract test suite that any implementation of es.EventStore can run to verify the documented behavior.
Package eventstoretest provides a contract test suite that any implementation of es.EventStore can run to verify the documented behavior.
memory
Package memory provides an in-memory es.EventStore (and es.EventStore) suitable for tests, examples, and local development.
Package memory provides an in-memory es.EventStore (and es.EventStore) suitable for tests, examples, and local development.
postgres module
sqlite module
examples
counter command
Command counter is an end-to-end demo of the synapse event sourcing toolkit.
Command counter is an end-to-end demo of the synapse event sourcing toolkit.
order command
Command order is an end-to-end demo of a richer event-sourced aggregate.
Command order is an end-to-end demo of a richer event-sourced aggregate.
process command
Command process is an end-to-end demo of the process-manager pattern: a Transfer aggregate that coordinates a multi-step workflow across two Account aggregates.
Command process is an end-to-end demo of the process-manager pattern: a Transfer aggregate that coordinates a multi-step workflow across two Account aggregates.
projection command
Command projection demonstrates the synapse subscription / projection machinery.
Command projection demonstrates the synapse subscription / projection machinery.
Package health provides liveness and readiness HTTP probes for synapse deployments.
Package health provides liveness and readiness HTTP probes for synapse deployments.
Package idgen provides event identifier generators for the synapse event sourcing toolkit.
Package idgen provides event identifier generators for the synapse event sourcing toolkit.
internal
testdomain
Package testdomain provides shared test fixtures — aggregates, events, commands, and a populated codec registry — for synapse's internal tests.
Package testdomain provides shared test fixtures — aggregates, events, commands, and a populated codec registry — for synapse's internal tests.
keystore
memory
Package memory provides an in-memory crypto.KeyStore suitable for tests, examples, and local development.
Package memory provides an in-memory crypto.KeyStore suitable for tests, examples, and local development.
postgres module
sqlite module
otel module
outbox
nats module
pgtest module
snapshotstore
memory
Package memory provides an in-memory es.SnapshotStore suitable for tests, examples, and local development.
Package memory provides an in-memory es.SnapshotStore suitable for tests, examples, and local development.
snapshotstorebench
Package snapshotstorebench provides a benchmark harness any implementation of es.SnapshotStore can run.
Package snapshotstorebench provides a benchmark harness any implementation of es.SnapshotStore can run.
snapshotstoretest
Package snapshotstoretest provides a contract test suite that any implementation of es.SnapshotStore can run to verify the documented behavior.
Package snapshotstoretest provides a contract test suite that any implementation of es.SnapshotStore can run to verify the documented behavior.
postgres module
sqlite module
timeoutstore
postgres module
sqlite module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL