Express an intention
Commands capture what should happen. Your domain decides whether it can.
Commands & aggregatesEvent sourcing & CQRS for Go.
Keep the history. Rebuild the state. Give your application a memory you can work with.
go get go-mink.devGo back in time. Select an event or hit replay.
A row tells you what is true now. An event stream tells you how you got here. go-mink gives you the building blocks to use both.
Commands capture what should happen. Your domain decides whether it can.
Commands & aggregatesAppend a fact to the stream. Version checks help protect against conflicting writes.
Streams & concurrencyTurn the same events into useful views. Replay history when your questions change.
Read models & projectionsStart with an event and a stream. Add the patterns your application needs, when it needs them.
func appendOrder(ctx context.Context, store *mink.EventStore) error {
// Register concrete types for typed replay.
store.RegisterEvents(OrderCreated{}, ItemAdded{})
events := []any{
OrderCreated{CustomerID: "customer-456"},
ItemAdded{SKU: "GO-01", Quantity: 2},
}
// NoStream rejects a second creation of this stream.
return store.Append(ctx, "order-123", events,
mink.ExpectVersion(mink.NoStream),
)
}
Plain Go structs, typed replay, and an explicit version check. Function excerpt; the complete example includes event types and store setup.
View complete examplePersistence is just the beginning. Compose the pieces you need for a system that evolves with your domain.
Append to streams with optimistic concurrency. Use PostgreSQL for persistence and memory for fast, isolated tests.
Explore the event storeBuild read models from events. Choose inline, asynchronous, or live projections and wire the execution explicitly.
Understand projectionsCoordinate multi-step processes with sagas. Publish committed events through a transactional outbox on supported adapters.
Connect your servicesField encryption, key management, and erasure tools help you implement your application’s data policies.
Explore data protectionDescribe behavior with Given / When / Then tests. Evolve event schemas with upcasters while keeping history readable.
Test your domainBuild an e-commerce application, from your first event to production concerns.
Follow the tutorial 02 / UNDERSTANDWork through event sourcing, CQRS, middleware, and projections in the article series.
Read the series 03 / EXPLOREFind the interfaces, patterns, and design decisions behind the toolkit.
Explore the APIEvent sourcing is a design choice.
Make it an informed one.
It is useful when history, traceability, rebuilding views, and complex domain behavior matter. It also adds schema evolution and operational responsibilities. For straightforward CRUD, a conventional database model may be simpler. Read the architecture guide.
No. The PostgreSQL adapter stores events in PostgreSQL. The memory adapter is useful for tests and local experiments; it is not durable storage. Explore adapters.
No. Appending an event and processing a projection are separate operations. Configure the projection engine and invoke inline processing, run asynchronous workers, or notify live projections according to your application’s needs. Understand projection strategies.
Upcasters help read older event schemas. Field encryption, erasure, and export capabilities support your data governance design; your retention policy and compliance obligations still need application-specific decisions. Read the security guide.
Open source. Plain Go. Ready for your domain.