Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Event Sourcing Bundle Laravel Package

patchlevel/event-sourcing-bundle

Symfony integration for the patchlevel event-sourcing library, built on Doctrine DBAL. It bundles snapshots, stream splitting, versioned subscriptions, upcasting, personal-data crypto-shredding, schema/migration setup, and CLI commands for a smooth developer experience.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The first thing to establish is a mismatch in the framing: this is a Symfony bundle, not a Laravel package. The value-add layer — DI extension, YAML/PHP config tree, console commands, tagged services — is Symfony-specific and will not load in a Laravel container. What is reusable is the underlying patchlevel/event-sourcing library plus Doctrine DBAL as the persistence substrate. So the realistic architecture is: adopt the core library, treat the bundle as a reference implementation for how to wire config, commands, and subscriptions, and write a thin Laravel service provider ourselves. Budget for that adapter work explicitly; it is not a composer require integration.

Integration feasibility. Moderate. The core library is well-scoped (aggregates, event store, snapshots, split streams, subscriptions/projections, upcasting, crypto-shredding) and "fully typed," which helps static analysis and onboarding. The friction points are: (1) Doctrine DBAL sits beside Eloquent rather than inside it, so we get a second connection and a second migration toolchain; (2) the bundle leans on Symfony Serializer and Symfony Uid conventions, which need mapping decisions against Laravel's serialization and ULID/UUID usage; (3) transactional consistency across the DBAL event store and Eloquent read models requires deliberate design, not defaults.

Technical risk. High, driven by adoption signals rather than code quality. 52 stars and 0 dependents means effectively no production reference base outside the vendor's own work. The dependency is close to single-vendor (Patchlevel), which is a bus-factor and roadmap-alignment risk. The positive counterweight is MIT licensing, published docs, an active release cadence, and a clean separation between core library and framework glue — meaning the exit cost is bounded if we keep our own adapter thin. Secondary risk: composer version pins on Symfony components (console, serializer, uid) can collide with Laravel's own pinned Symfony dependencies; this must be resolved in a spike before any commitment.

Key questions for the maintainer / spike.

  • Is the core library formally supported as framework-agnostic, and are Laravel/Symfony-agnostic adapters a stated roadmap item?
  • Who owns the event-store schema and its migrations — the package, or us? What is the upgrade contract for table changes?
  • Which Symfony components are hard requirements vs. optional, and what is the minimum viable dependency set?
  • What is the recommended pattern for subscription workers (long-running process, graceful shutdown, gap/stall detection)?
  • Where do crypto-shredding keys live, and what is the supported KMS integration?
  • What is the documented process for projection rebuilds and for upcaster versioning on a live store?
  • Any known production deployments, and at what stream volume?

Integration Approach

Stack fit. Treat this as infrastructure, not application code. The event store lives on Doctrine DBAL; read models and the rest of the app stay on Eloquent. That means: a dedicated DBAL connection configured through Laravel's database.php (sharing credentials/DSN but separate connection object), Doctrine Migrations or a hand-rolled Laravel migration path for the event-store tables, and an explicit rule that only the event store writes through DBAL and only projections write through Eloquent. Do not let the two share transaction boundaries casually.

Migration path. There is no incremental migration from an existing Eloquent-based aggregate — event sourcing is a rewrite of the write model for whichever bounded context adopts it. The realistic path is a strangler pattern on a single, low-risk bounded context: keep the existing Eloquent model authoritative, run the event-sourced model in parallel behind a feature flag, dual-write briefly for validation, then cut reads over. Backfilling historical state means synthesizing an initial event stream from existing rows, which is a one-way, idempotent, well-tested job.

Compatibility. Verify in the spike: PHP version floor, Laravel major version, DBAL major version, and a resolved composer.lock that does not downgrade Laravel's Symfony component pins. Also confirm the DB platform — Postgres is the safer assumption than MySQL for advisory locks and concurrent subscription handling; validate explicitly if we are MySQL-standardized.

Sequencing.

  1. Spike (1–2 weeks): install core library, write a minimal service provider, stand up one aggregate with two events, one projection, and a snapshot. Prove replay from scratch.
  2. Adapter hardening: config publishing, artisan commands for stream inspection and subscription management, worker command compatible with Supervisor/Horizon-style supervision.
  3. Pilot bounded context: strangler rollout with dual-write validation and a documented rollback (flag off, Eloquent remains authoritative).
  4. Operational readiness: dashboards for stream lag, projection lag, subscription stall; runbook for rebuilds and upcaster rollouts.
  5. Second context only after the pilot has survived a schema upgrade and one upcaster change.

Operational Impact

Maintenance. We own the Laravel adapter — that is permanent, non-trivial maintenance: it must track both the upstream library's release cadence and Laravel's major-version churn. Pin to exact versions, keep the adapter under ~500 lines, and forbid leakage of package types into domain code so the library remains swappable. Upstream upgrades are not routine patch bumps: a change to serialization format or event-store schema on a populated store is a migration project.

Support. No commercial support, no SLA, small maintainer pool, no visible dependent base. Escalation path for a production defect is a GitHub issue. Mitigation: budget internal ownership from day one, and consider a support or consulting arrangement with the vendor given they are a commercial entity — treat that as a procurement line item, not a hope.

Scaling. Three cost curves to model. (1) Storage: append-only event tables grow monotonically; snapshots reduce replay cost but not table size, so partitioning or archival policy is a day-one design decision, not a quarter-three problem. (2) Replay: projection rebuilds are full scans; on a large store these become multi-hour operations that need a blue/green projection strategy. (3) Workers: subscriptions and processors are long-running daemons requiring supervision, memory-leak hygiene, restart policy, and per-subscription concurrency control — a materially different operational shape from queue workers.

Failure modes to design for.

  • Dual-write divergence during migration — requires a reconciliation check, not just logs.
  • Poison events stalling a subscription — need dead-letter/park-and-continue semantics, otherwise one bad event halts projections indefinitely.
  • Crypto-shredding key loss — deliberately irreversible; a lost key permanently destroys personal data in the stream and may break replay. Key custody must be documented and tested.
  • Broken upcasters — an upcaster bug corrupts replay silently and retroactively; requires replay-tested upcasters in CI.
  • Snapshot desync — a snapshot that does not match stream state yields subtly wrong aggregates; validate on version.
  • Split-stream misconfiguration — cross-stream invariants are lost by definition; needs an explicit rule that split streams carry no invariant dependencies.

Ramp-up. The team is signing up for two learning curves simultaneously: event sourcing as a paradigm (eventual consistency, replay, versioning, projection design) and Doctrine DBAL tooling in a Laravel shop. Realistic ramp: 2–3 weeks for a competent senior engineer to be productive in the spike, 6–8 weeks before the team can operate a projection in production without hand-holding. Mitigate with a written internal standard for event naming/versioning, a review checklist for upcasters, a replay exercise as part of onboarding, and vendor documentation reading as required pre-work.

Recommendation. Conditional go, scoped to a single bounded context with a proven rollback and a deliberately thin adapter. The library's feature completeness (snapshots, split streams, subscription lifecycle, crypto-shredding, upcasting) genuinely reduces build cost, and MIT licensing bounds the downside. But 0 dependents, no Laravel-native path, and single-vendor concentration mean this is an adopt-with-our-own-ownership decision, not a dependency we can lean on. Approve the spike; gate the pilot on a resolved dependency graph and a working subscription worker.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle