Event sourcing · PHP 8.4+

Type-safe PHP for event-driven systems.

A family of modern, well-tested open source libraries for event sourcing and KurrentDB (formerly EventStoreDB) — from a low-level HTTP client to a batteries-included Symfony bundle.

6
libraries
8.4+
php version
PSR
7 · 17 · 18
MIT
licensed
🐉

About the name — Ouro was the friendly green dragon mascot of the original EventStore. It's not part of the official branding anymore, but we always had a soft spot for the little guy. Friends of Ouro is our nostalgic tip of the hat: same love for event sourcing, carried forward into the KurrentDB era.

// the event stream

Every project, in order of appearance.

The libraries that make up the family — append-only, just how we like it.

📦

KurrentDB PHP start here

friendsofouro/kurrentdb-php
★ 5

A convenience metapackage that bundles the core client with sensible default dependencies. The fastest way to go from composer require to writing events — most people should start here.

good defaultsquick setupmetapackage
$ composer require friendsofouro/kurrentdb-php
GitHub repository
🏗️

KurrentDB PHP Core

friendsofouro/kurrentdb-core
★ 69

The flagship client for the KurrentDB HTTP API. Strict typing, stream management, optimistic concurrency, forward/backward iteration, batch operations and HTTP caching — all PSR-7/18 compliant.

stream r/w/deleteoptimistic concurrencybatch opsPSR-7/18
$ composer require friendsofouro/kurrentdb-core
Documentation & source
🎯

KurrentDB Symfony Bundle

friendsofouro/kurrentdb-bundle
★ 3

Seamless Symfony 7.3+ integration — service container wiring, configuration management and auto-wiring so KurrentDB feels native to your application.

Symfony 7.3+auto-wiringDI config
$ composer require friendsofouro/kurrentdb-bundle
Bundle documentation
🔌

HTTP Batch Contract

friendsofouro/http-batch-contract

PSR-18 interface contracts for sending many HTTP requests efficiently. Type-safe batch responses, exception aggregation and transformation utilities — the backbone of the core client's batched reads.

PSR-18interfacesexception aggregation
$ composer require friendsofouro/http-batch-contract
Contract documentation

HTTP Batch Guzzle

friendsofouro/http-batch-guzzle

A high-performance Guzzle implementation of the batch contract — concurrent request processing, built-in HTTP caching with filesystem and APCu adapters, plus retry logic.

concurrentHTTP cachingAPCu / filesystem
$ composer require friendsofouro/http-batch-guzzle
Implementation guide
🐳

KurrentDB Docker Example

FriendsOfOuro/kurrentdb-docker-example

A ready-to-use Docker Compose setup for running KurrentDB locally. One command up, web UI on :2113, persistent storage — perfect for development and testing.

docker composeweb UI :2113persistent data
$ git clone git@github.com:FriendsOfOuro/kurrentdb-docker-example.git
Get the Docker setup
// quick start

Write your first event in minutes.

Spin up KurrentDB with the Docker example, install the metapackage, and you're appending events to a stream.

install.sh
# 1. Start KurrentDB locally
docker compose up -d

# 2. Install the metapackage (core client + sensible defaults)
composer require friendsofouro/kurrentdb-php
first-event.php
<?php

use KurrentDB\EventStore;
use FriendsOfOuro\Http\Batch\Guzzle\GuzzleHttpClient;
use KurrentDB\WritableEvent;
use KurrentDB\ValueObjects\Identity\UUID;
use GuzzleHttp\Psr7\HttpFactory;

// Create the client
$httpFactory = new HttpFactory();
$httpClient  = new GuzzleHttpClient();

$eventStore = new EventStore(
    $httpFactory->createUri('http://admin:changeit@127.0.0.1:2113'),
    $httpFactory,  // UriFactory
    $httpFactory,  // RequestFactory
    $httpClient,
);

// Write an event
$event = new WritableEvent(
    new UUID(),
    'user-registered',
    ['userId' => '123', 'email' => 'user@example.com'],
);

$version = $eventStore->writeToStream('user-123', $event);

// Read the stream back
foreach ($eventStore->forwardStreamFeedIterator('user-123') as $entry) {
    echo 'Event: ' . $entry->getEvent()->getType() . PHP_EOL;
}
🧊

Strictly typed

Modern PHP 8.4+ with value objects and strict types throughout — fewer runtime surprises.

🔒

Optimistic concurrency

Expected-version checks make safe, conflict-aware writes a first-class concern.

🧪

Well tested

Comprehensive suites and CI across the family, so you can upgrade with confidence.

📋

Requirements

PHP 8.4 or higher · a KurrentDB server instance · Composer for package management.

🤝

Contributing

Each repo has its own guidelines. Open issues, send PRs, or start a discussion — newcomers welcome.

📜

License

Everything is released under the permissive MIT license. Build freely, commercial or otherwise.