PHPackages                             botilka/botilka - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. botilka/botilka

ActiveLibrary[Framework](/categories/framework)

botilka/botilka
===============

CQRS &amp; Event Sourcing framework

1.2.0(6y ago)352.8k4[1 issues](https://github.com/botilka/botilka/issues)MITPHPPHP &gt;=7.1CI failing

Since Dec 17Pushed 2y ago3 watchersCompare

[ Source](https://github.com/botilka/botilka)[ Packagist](https://packagist.org/packages/botilka/botilka)[ RSS](/packages/botilka-botilka/feed)WikiDiscussions master Synced 3d ago

READMEChangelog (7)Dependencies (23)Versions (9)Used By (0)

BOTILKA
=======

[](#botilka)

[![Build Status](https://camo.githubusercontent.com/bc69191a58eb0767e668baf04882044eb908dcead51a654835e2633c5c424438/68747470733a2f2f7472617669732d63692e6f72672f626f74696c6b612f626f74696c6b612e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/botilka/botilka)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/fa6b8b496e52e6f231930540e689722b5f536d4761cab896ac41a64a37875a47/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f626f74696c6b612f626f74696c6b612f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/botilka/botilka/?branch=master)[![Code Coverage](https://camo.githubusercontent.com/617cc2dadd07ddc907496829dd440399cbcbbeeb1c2533f48fe80a77d32a586e/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f626f74696c6b612f626f74696c6b612f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/botilka/botilka/?branch=master)[![PHPStan](https://camo.githubusercontent.com/441b5874ce4df0a2defc892979c96c46889b69cb32119d04f0b48626349f8bc9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d656e61626c65642d627269676874677265656e2e7376673f7374796c653d666c6174)](https://github.com/phpstan/phpstan)[![Infection MSI](https://camo.githubusercontent.com/7eee93042325af54c48a9b322f10c8314fb4b11253baaa757bb4c21c531065a6/68747470733a2f2f62616467652e737472796b65722d6d757461746f722e696f2f6769746875622e636f6d2f626f74696c6b612f626f74696c6b612f6d6173746572)](https://infection.github.io)

An modern &amp; easy-to-use Event Sourcing &amp; CQRS library. It's shipped with implementations built on top of Symfony components.

It can leverage [API Platform](https://api-platform.com) to expose yours `Commands` and `Queries` via REST.

Features
--------

[](#features)

- EventStore implementation with [Doctrine](https://www.doctrine-project.org/) or [MongoDB](https://www.mongodb.com).
- Snapshot store for performance (Doctrine &amp; MongoDB).
- Swagger commands &amp; queries description (via API Platform UI).
- REST API access to commands &amp; queries.
- Sync or async event handling is a matter of configuration.
- Event replaying (allow to test domain changes).
- Projection re-play on demand (ie. when you add a ReadModel).
- Safe commands concurrency (optimistic locking).
- Tested, good code coverage.

Configuration
-------------

[](#configuration)

An event store should (must) be persisted and the default implementation is not! Choose between:

- `Botilka\Infrastructure\Doctrine\EventStoreDoctrine`
- `Botilka\Infrastructure\MongoDB\EventStoreMongoDB`

```
# config/packages/botilka.yaml
botilka:
    # default implementation is 'Botilka\Infrastructure\InMemory\EventStoreInMemory', not persisted!!
    event_store: Botilka\Infrastructure\Doctrine\EventStoreDoctrine # or 'Botilka\Infrastructure\MongoDB\EventStoreMongoDB'
```

Botilka provide a command to create &amp; configure the event store:

```
bin/console botilka:store:initialize event doctrine # or mongodb
```

You can force recreate, but be carefull, you will lost all the previous events:

```
bin/console botilka:store:initialize event doctrine -f
```

Usage
-----

[](#usage)

### CQRS &amp; EventSourcing

[](#cqrs--eventsourcing)

You'll need to create Commands, Queries, Events and so on. [Read the documentation](/documentation/cqrs.md).

### Async command handling

[](#async-command-handling)

You may need to handle some or all commands asychonously. Using [Symfony Messenger](https://symfony.com/doc/current/messenger.html#transports-async-queued-messages), you'll need to configure it:

```
# config/packages/messenger.yaml
framework:
    messenger:
        transports:
            async: "%env(MESSENGER_TRANSPORT_DSN)%"
        routing:
            'Botilka\Application\Command\Command': async
```

### Snapshots

[](#snapshots)

When dealing with a lots of events, snapshotting is a good way to keep up on performance. [Read the documentation](/documentation/snapshot.md).

### Event replaying

[](#event-replaying)

It you've added or changed a business rule, you may want to see how it would have behaved with the event stream, this is a use case for event replaying.

You can replay event by aggregate id or by domain.

Let's say your a bank. The BI team said they want to send a SMS each time withdrawal is made if amount is more than a value and they want to know how many SMS would have been sent. You have to:

1. create the new event handler
2. re-play events

The event

```
final class SendSMSOnWithdrawalPerformed implements EventHandler
{
    public function onWithdrawalPerformed(WithdrawalPerformed $event): void
    {
        $user = $this->userRepository->getOwner($event->getgetAccountId());
        if ($this->isMobilePhone($phoneNumber = $user->getPhoneNumber()) && $event->getAmount() > self::ALERT_AMOUNT) {
            // record the calls count somewhere, now you know how many SMS would have been sent
            $this->smsSender->send($phoneNumber);
        }
    }
}
```

Replay:

```
# by domain
bin/console botilka:event_store:replay --domain [domain name]
# or by id
bin/console botilka:event_store:replay --id [aggregate root id] # you can limit the scope with --from/-f & --to/-t
```

### Projection replay

[](#projection-replay)

In the same way than replaying events, you can replay projection. If you've added a projection and you want to replay only this projection, use the `--matching/-m` options.

> Matching is a regex matched against `[ProjectorFQCN]::[method]`, ie. `App\BankAccount\Projection\Doctrine\BankAccountProjector::sumOfDeposit`

The projection

```
namespace App\BankAccount\Projection\Doctrine;

final class BankAccountProjector implements Projector
{
    public function sumOfDeposit(DepositPerformed $event): void
    {
        $stmt = $this->connection->prepare('UPDATE all_the_sums SET value = value + :amount WHERE type = :type');
        $stmt->prepare(['amount' => $event->getAmount(), 'type' => 'deposit']);
        $stmt->execute();
    }

    public static function getSubscribedEvents()
    {
        return [
            DepositPerformed::class => 'sumOfDeposit',
        ];
    }
}
```

Replay projection:

```
# by domain
bin/console botilka:projector:build domain [domain name]
# or by id
bin/console botilka:projector:build id [aggregate root id]  --matching sumOfDeposit # you can limit the scope with --from/-f & --to/-t
```

### API Platform bridge

[](#api-platform-bridge)

See the [API Platform bridge](/documentation/api_platform_bridge.md) documentation.

Testing
-------

[](#testing)

This project uses PHP Unit: `vendor/bin/phpunit`.

Functionals tests are grouped under the tag `functional`: `vendor/bin/phpunit --group functional`.

How it works
------------

[](#how-it-works)

Have a look [here](/documentation/internals.md) to better understand the design choices made and how the magic stuff happens.

### todo

[](#todo)

- Event upcasting.
- (maybe) Saga / Process manager.
- (maybe) Smart command retry on concurrency exception.

### Resources

[](#resources)

-
-
-  (uses Broadway)
-
-
-
-  \[french\]
- [https://www.youtube.com/watch?v=VpzSMz\_XbqM](https://www.youtube.com/watch?v=VpzSMz_XbqM) \[french\]

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance19

Infrequent updates — may be unmaintained

Popularity28

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor1

Top contributor holds 93.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~30 days

Recently: every ~42 days

Total

7

Last Release

2520d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/00d16470446064d16599e10551ecc9081b122071f493c104129d7e2fdd53ed31?d=identicon)[azzra](/maintainers/azzra)

---

Top Contributors

[![azzra](https://avatars.githubusercontent.com/u/9268494?v=4)](https://github.com/azzra "azzra (46 commits)")[![alunys](https://avatars.githubusercontent.com/u/7555921?v=4)](https://github.com/alunys "alunys (3 commits)")

---

Tags

symfonybundlecqrsesEventSourcingapi-platform

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/botilka-botilka/health.svg)

```
[![Health](https://phpackages.com/badges/botilka-botilka/health.svg)](https://phpackages.com/packages/botilka-botilka)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M651](/packages/sylius-sylius)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k15.4k](/packages/prestashop-prestashop)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.2M386](/packages/shopware-core)[ec-cube/ec-cube

EC-CUBE EC open platform.

78527.0k1](/packages/ec-cube-ec-cube)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
