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

Eventually Laravel Package

altek/eventually

Eventually is a Laravel event sourcing package for modeling applications around domain events. It offers aggregates, event storage, projectors, and reactors, giving you an expressive way to persist state changes as an append-only event log.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. altek/eventually is a narrow, single-responsibility Eloquent extension: it adds lifecycle events to many-to-many pivot operations (attach/detach/sync and pivot-row saves) that older Laravel versions did not dispatch natively. Architecturally it is a leaf dependency — it does not shape the domain model, and it should never become load-bearing for core business logic. Its real value is as a cross-cutting hook point: it lets teams express pivot side-effects (audit logging, cache invalidation, search-index sync, notifications) declaratively instead of scattering them across service methods. That is a legitimate pattern, but it is a convenience layer, not architecture.

Integration feasibility. The integration surface is likely small (a service provider plus a trait applied to models, or a replacement relationship class), so the effort to try it is low. The gating question is composer compatibility: this package appears to originate in the Laravel 5.x era, and a modern Laravel 10/11 application will almost certainly reject its illuminate/* constraints without a fork. Feasibility is therefore not "can we install it" but "is it worth forking an unmaintained package to reproduce behavior the framework now ships natively."

Technical risk. Low blast radius, high uncertainty. All the usual signals are absent: zero stars, zero dependents, no community validation, no visible maintenance cadence. More importantly, Laravel has offered native pivot events (pivotAttaching, pivotAttached, pivotDetaching, pivotDetached, pivotUpdating, pivotUpdated) via custom pivot models and the AsPivot trait since the 8.x line. That creates a strong obsolescence risk: adopting this package means adopting a dead-end that duplicates framework behavior and will need to be unwound at the next major upgrade. Secondary risks are behavioral rather than structural — event-semantics mismatches and conflicts with other packages that override BelongsToMany (soft-deleting pivots, enhanced many-to-many packages, custom pivot models).

Key questions.

  • Which Laravel and PHP versions are actually supported, and do the composer constraints resolve against our target?
  • Which operations dispatch events — attach, detach, sync, syncWithoutDetaching, toggle, updateExistingPivot, updateOrCreate? Are events per-row or per-batch?
  • Do events fire before or after the database write, and inside or outside the ambient transaction? This determines whether listeners see committed state.
  • How does it interact with native Pivot/AsPivot classes — double dispatch, silent override, or clean coexistence?
  • Is the event dispatch unit-testable in isolation, and is there a license and named maintainer?
  • What is the actual business requirement driving pivot events? If the answer is "audit trail on relationship changes," could a domain event or an observer on an explicit join model satisfy it more durably?

Integration Approach

Stack fit. Only a fit if the application is on a Laravel version predating native pivot events and there is a genuine, documented need for pivot-level side-effects. On Laravel 8+ this package is redundant, and the correct stack fit is "do not adopt." If the team is on an older LTS and cannot upgrade soon, the package is a reasonable stopgap — provided it is wrapped.

Migration path. Adopting it should be treated as a one-way door until a planned exit. The exit is well-defined: replace the package trait with AsPivot on pivot models, and rename listeners from the package's event names to Laravel's pivot* names. That migration is mechanical if — and only if — the application dispatches through an internal abstraction rather than referencing package events directly. If the team is already on Laravel 8+, there is no migration into this package worth doing; the migration is away from the legacy pattern, and this package should be recorded in the ADR as "considered and rejected."

Compatibility. Verify three things before writing code: composer constraint resolution against the pinned framework and PHP version; coexistence with any package that subclasses or decorates BelongsToMany; and behavior under pivot soft deletes, custom pivot columns, and polymorphic many-to-many. Compatibility failures here tend to surface at runtime in specific relationship code paths, not at install time, so a spike must exercise every distinct relationship shape in the app.

Sequencing.

  1. Confirm the requirement: enumerate the exact pivot operations that need side-effects and what each listener must do.
  2. Confirm the framework baseline: if Laravel ≥8, close the evaluation and standardize on native pivot events.
  3. If on an older baseline, time-box a spike (half a day) covering attach, detach, sync, and transaction rollback behavior.
  4. If it passes, wrap it: define internal domain events and have exactly one adapter dispatch them, so the package is swappable and never referenced elsewhere.
  5. Pin the exact version, fork to an internal namespace if the upstream constraints are stale, and open a ticket to retire the dependency at the next framework upgrade.

Operational Impact

Maintenance. Treat this as at-risk, effectively vendored code. There is no meaningful upstream maintenance signal, so the internal team owns it from day one. That means a pinned version, a README note explaining why it exists, and a tested fork path. The total surface is small enough that forking is cheap — which is the main argument in its favor if the legacy constraint is real.

Support. No community to escalate to and no dependents to observe for failure patterns; every incident is first-occurrence. Internal ownership needs to be explicit — a named team, not "whoever wrote it." Budget for the fact that debugging "why didn't my listener fire" requires knowing which code paths the package instruments, which is tribal knowledge unless documented.

Scaling. The package itself is not a throughput concern; event dispatch is cheap relative to the writes it accompanies. The scaling risk is in the listeners. sync() on a large collection can fire one event per row, and if each listener issues a query, a bulk relationship update becomes an N+1 storm inside a single request. Any listener attached to pivot events should be queued or batched, and bulk operations should be load-tested rather than assumed.

Failure modes.

  • Silent no-fire: a code path performs the pivot write without dispatching — listener never runs, side-effect silently skipped. This is the worst failure mode because it is invisible until data drifts.
  • Double dispatch: package events plus native events both firing after an upgrade or in mixed code, producing duplicate audit rows or duplicate notifications.
  • Transaction leakage: events firing inside an uncommitted transaction, so listeners act on data that later rolls back — external systems get phantom state.
  • Upgrade breakage: a Laravel major bump changes relationship internals and the package's overrides stop applying, without a hard error.
  • Relationship-class conflict: another package decorating BelongsToMany wins the boot order and the package quietly stops functioning.

Ramp-up. Learning the API is trivial — an hour for a mid-level developer. The real ramp-up cost is conceptual: understanding event timing, transaction semantics, and which operations are instrumented. That is roughly a half-day of onboarding plus a one-page internal note. Given the zero-traction signals, the 55.25 opportunity score reads correctly as "cheap to try, low strategic value." The right posture is a time-boxed spike and an ADR, not a roadmap commitment — and on any modern Laravel baseline, the likely verdict is to adopt the framework-native equivalent and skip this dependency entirely.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource